swapd() undefined behavior?

H

hjanssen2

Hi

in the following source code, I think swap32() itself should be ok,
while I am unsure if swapd() and swapd_wrap() invoke undefined
behavior.
The doubt is reinforced by gcc -O3 giving strange results with the
latter.
Any comments?

Specifically, consider a function that receives a double parameter and
returns a
double parameter like:

double func( double d )
{
// return d after whatever bit manipulations imaginable
}

that is used like:

double d1=SOME_VALUE, d2;

d2 = func(d1);

Will the parameter passing and the assignment in this code have to
preserve the
bit pattern? Even if d1 or d2 are unnormalized or NaN?

thanks for your attention
Herbert

/*
swapd.c

programs compiled with gcc 3.3.3 with
gcc -std=c99 -O3 -pedantic -W -Wall swapd.c -o swapd
and
gcc -std=c99 -pedantic -W -Wall swapd.c -o swapd
yield different results
*/

#include <stdio.h>
#include <stdint.h>

// reverse order of bytes in 32bit word, no undefined behavior, right?
void swap32( int32_t *in,
int32_t *out )
{
char *p_in = (char*)in;
char *p_out = (char*)out;

p_out[0] = p_in[3];
p_out[1] = p_in[2];
p_out[2] = p_in[1];
p_out[3] = p_in[0];
}

int32_t swap32_wrap( int32_t in )
{
int32_t ret;

swap32( (void*)&in, (void*)&ret );

return ret;
}

double swapd( double d )
{
double ret;
int32_t *p_out = (void*)&ret;
int32_t *p_in = (void*)&d;

swap32( &p_in[1], &p_out[0] );
swap32( &p_in[0], &p_out[1] );

return ret;
}

double swapd_wrap( double d )
{
double ret;
int32_t *p_out = (void*)&ret;
int32_t *p_in = (void*)&d;

p_out[0] = swap32_wrap( p_in[1] );
p_out[1] = swap32_wrap( p_in[0] );

return ret;
}

int main(void)
{
double d_init = 1.23456e7;
double d = 0;
double ds = 0;
double ds2;

fprintf( stderr, "sizeof(double) = %d:\n", sizeof(double) );

d = d_init;
ds = swapd( d );
ds2 = swapd( ds );
fprintf( stderr, "swapd():\n" );
fprintf( stderr, "d = %.8e\n", d );
fprintf( stderr, "ds = %.8e\n", ds );
fprintf( stderr, "ds2 = %.8e\n", ds2 );
fprintf( stderr, "ds2 - d = %.8e\n", ds2-d );

d = d_init;
ds = swapd_wrap( d );
ds2 = swapd_wrap( ds );
fprintf( stderr, "swapd_wrap():\n" );
fprintf( stderr, "d = %.8e\n", d );
fprintf( stderr, "ds = %.8e\n", ds );
fprintf( stderr, "ds2 = %.8e\n", ds2 );
fprintf( stderr, "ds2 - d = %.8e\n", ds2-d );

/*
with -03 prints:

sizeof(double) = 8:
swapd():
d = 1.23456000e+07
ds = 2.69795606e-315
ds2 = 1.23456000e+07
ds2 - d = 0.00000000e+00
swapd_wrap():
d = 1.23456000e+07
ds = 1.16542096e-314
ds2 = -1.99574670e+00
ds2 - d = -1.23456020e+07
*/

/*
without -03 prints:

sizeof(double) = 8:
swapd():
d = 1.23456000e+07
ds = 2.69795606e-315
ds2 = 1.23456000e+07
ds2 - d = 0.00000000e+00
swapd_wrap():
d = 1.23456000e+07
ds = 2.69795606e-315
ds2 = 1.23456000e+07
ds2 - d = 0.00000000e+00
*/

return 0;
}
 
?

=?ISO-8859-1?Q?=22Nils_O=2E_Sel=E5sdal=22?=

Hi

in the following source code, I think swap32() itself should be ok,
while I am unsure if swapd() and swapd_wrap() invoke undefined
behavior.
Please use masks and shift if you want to be correct.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top