Bug 27533 - wrong result after reinterpret_cast from float* to int*
Summary: wrong result after reinterpret_cast from float* to int*
Status: RESOLVED DUPLICATE of bug 21920
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.1.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-05-10 14:45 UTC by ulrich lauther
Modified: 2006-05-10 17:53 UTC (History)
59 users (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Complete tiny example exposing the problem (207 bytes, text/plain)
2006-05-10 14:53 UTC, ulrich lauther
Details
same as before, but stdio.h expanded (4.43 KB, text/plain)
2006-05-10 14:55 UTC, ulrich lauther
Details

Note You need to log in before you can comment on or make changes to this bug.
Description ulrich lauther 2006-05-10 14:45:39 UTC
The code

inline int almost_equal(float a, float b, int maxUlps = 16) {
  int intDiff = *(reinterpret_cast<int*>(&a)) -
                    *(reinterpret_cast<int*>(&b));
  printf("intDiff %d\n",intDiff);
  return intDiff;
}

gives different results when compiled with and without -O2
(yes, floats are involved, but it has nothing to do with rounding)
Comment 1 Pawel Sikora 2006-05-10 14:51:52 UTC
you're violating the aliasing rules, so use -fno-strict-aliasing option.
Comment 2 ulrich lauther 2006-05-10 14:53:27 UTC
Created attachment 11434 [details]
Complete tiny example exposing the problem

I submit this version that includes stdio.h for readability, expanded version will follow
Comment 3 ulrich lauther 2006-05-10 14:55:12 UTC
Created attachment 11435 [details]
same as before, but stdio.h expanded
Comment 4 Volker Reichelt 2006-05-10 14:59:09 UTC
As Pawel already pointed out:
Your code is brokan as you are violating the aliasing rules.

Please read about this in the non-bug section of http://gcc.gnu.org/bugs.html :
"Casting does not work as expected when optimization is turned on."


*** This bug has been marked as a duplicate of 21920 ***
Comment 5 Pawel Sikora 2006-05-10 15:26:27 UTC
(In reply to comment #0)
> The code
> 
> inline int almost_equal(float a, float b, int maxUlps = 16) {
>   int intDiff = *(reinterpret_cast<int*>(&a)) -
>                     *(reinterpret_cast<int*>(&b));

if you really need such casting and still use strict-aliasing
you should rewrite almost_equal().

/*inline*/ int almost_equal( float a, float b )
{
        int ia;
        memcpy( &ia, &a, sizeof(int) );
        int ib;
        memcpy( &ib, &b, sizeof(int) );
        return ( ia - ib );
}

compiler will optimize it nicely ;)

00000000 <almost_equal(float, float)>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 ec 10                sub    $0x10,%esp
   6:   8b 45 08                mov    0x8(%ebp),%eax    <===
   9:   2b 45 0c                sub    0xc(%ebp),%eax    <===
   c:   c9                      leave
   d:   c3                      ret