optimization bug in g++ 4.3.3

Ed Boas ed.boas@gmail.com
Sat Sep 5 05:50:00 GMT 2009


Got it, thanks!  Using a union instead of

int32_t i=*(int32_t*)&x

fixes the problem.

Thanks,
Ed

On Fri, Sep 4, 2009 at 5:56 PM, Tim Prince<n8tm@aol.com> wrote:
> Ed Boas wrote:
>>
>> The following code:
>>
>> ----------
>> #include <stdio.h>
>> #include <inttypes.h>
>>
>> // Rounds in current rounding mode, which is "round to closest
>> integer" by default on Pentium & Xeon
>> // Valid for |fval| <= 2^22 - 1, that is, -4194303 <= fval <= 4914303
>> // based on code from www.lomont.org
>> inline int32_t fast_round(float x) {
>>  x+=12582912; // 2^23+2^22
>>  int32_t i=*(int32_t*)&x;
>>  i&=8388607; // 2^23-1;
>>  i-=4194304; // 2^22
>>  return i;
>> }
>>
>> int main(void) {
>>  printf("%f rounds to %i\n", 1.4f, fast_round(1.4f));
>>  return 0;
>> }
>> ----------
>>
>> produces the correct output when compiled using g++ -O:
>>
>> 1.400000 rounds to 1
>>
>> However, when it is compiled with g++ -O2, it prints:
>>
>> 1.400000 rounds to -4194304
>>
>
>
> $ gcc -Wall  -O2  ed.c
> ed.c: In function 'int32_t fast_round(float)':
> ed.c:9:25: warning: dereferencing type-punned pointer will break
> strict-aliasing
>  rules
>
> TCPRINCE@tcprince-MOBL5 /cygdrive/c/Documents and Settings/tcprince/My
> Documents
> /tim/tim/src/net
> $ ./a
> 1.400000 rounds to 1
>
> gcc 4.5 doesn't show the problem of gcc 4.3.2 on this broken source code.
>  You invoke Undefined Behavior with a past release of gcc, you get what you
> paid for.  Who's to say what is "correct output?"
>
> Set -no-strict-aliasing, the warning goes away, and even gcc 4.3 gives your
> "correct output."
>



-- 
________________________________
F. Edward Boas
3375 Alma St # 166
Palo Alto, CA 94306
650-787-1688
http://www.stanford.edu/~boas



More information about the Gcc-help mailing list