function with side effects ignored
Andrew Haley
aph@redhat.com
Tue Sep 29 17:18:00 GMT 2009
Matthew Woehlke wrote:
> Using gcc-4.3.2-7.x86_64 (Fedora 10).
>
> I have these functions:
>
> void my_ntoh_float(float *f)
> {
> int p = (int*)f;
> *p = ntohl(*p);
> }
>
> float my_get_float(const void * buffer)
> {
> float value;
> memcpy(&val, buffer, sizeof(float);
> my_ntoh_float(&value);
> return value;
> }
>
> ...which is compiled (-O2) like so:
> <my_get_float+0>: push %ebp
> <my_get_float+1>: mov %esp,%ebp
> <my_get_float+3>: sub $0x10,%esp
> <my_get_float+6>: mov 0x8(%ebp),%eax
> <my_get_float+9>: mov (%eax),%eax
> <my_get_float+11>: mov %eax,-0x4(%ebp)
> <my_ntoh_float+0>: mov -0x4(%ebp),%eax
> <my_get_float+17>: flds -0x4(%ebp)
> <my_ntoh_float+6>: ror $0x8,%ax
> <my_ntoh_float+10>: ror $0x10,%eax
> <my_ntoh_float+13>: ror $0x8,%ax
> <my_ntoh_float+17>: mov %eax,-0x4(%ebp)
> <my_get_float+34>: leave
> <my_get_float+35>: ret
>
> Now, obviously this is not going to work correctly; the result of the
> call to my_ntoh_float is effectively discarded. Is the bug in the code,
> or in gcc? In either case, is there a way (besides dropping
> optimizations) to fix this that doesn't involve non-portable code?
It's in your code. You're accessing an object (p) as an incompatible type.
See C99, Section 6.3.2.3 for all the details.
Do this:
float my_ntoh_float(float f)
{
union
{
int i;
float f;
} u;
u.f = f;
u.i = ntohl(u.i);
return u.f;
}
float my_get_float(const void * buffer)
{
float value = *(float*)buffer;
value = my_ntoh_float(value);
return value;
}
Which generates this:
my_get_float:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl 8(%ebp), %eax
movl (%eax), %eax
bswap %eax
movl %eax, -4(%ebp)
flds -4(%ebp)
leave
ret
Andrew.
More information about the Gcc-help
mailing list