I'd try using a union something like this: void my_ntoh_float(float *f) { union { int li; float lf; }; lf = *f; li = ntohl(li); *f = lf; } Brian On Tue, Sep 29, 2009 at 9:58 AM, Matthew Woehlke <mw_triad@xxxxxxxxxxxxxxxxxxxxx> 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? > > (Incidentally, there is at least one gcc "bug" here, in that the instruction > at my_ntoh_float+0 is superfluous.) > > -- > Matthew > Please do not quote my e-mail address unobfuscated in message bodies. > -- > "It's not easy for [Microsoft] to accept [competing fairly]" > -- Dave Heiner (a Microsoft VP, paraphrased) >