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.