1

I have a large program that has a large number of fragments of the form

float t = amplitudes->read(current_element);
    if ( *((uint32_t * ) &t) == 0xsomereservedvalue)
         do_something
     else
          do_something_else

This compiles fine with gcc 3.4.x no warnings. Compiled with -Wtrict-aliasing=2 still no warnings. I recently tried compiling with gcc4.4 and got a vast number of warnings about type punned references. Can someone tell me is there any reasonable situation under which this sort of code can fail? As far as I can see, type punning is only a potential issue if optimizations arrange things such that something might be written back from a register after another line of code reads it, which since we're on the return of a function here simply can't happen. Am I missing something here, or is gcc being somewhat braindead?

camelccc
  • 2,847
  • 8
  • 26
  • 52

2 Answers2

1

Of course it warns. I just checked gcc 4.8.2 it warns too. Imagine, that float size for target machine is 16 bit and you are trying to read 32 bits after data bounds. It is UB.

btw I disagree with reinterpret_cast usage in this case. The only useful way for reinterpret_cast is *(reinterpret_cast<char *>(&t)), even *(reinterpret_cast<unsigned *>(&t)) will still break aliasing rules, and you'll get the same warning. That is because compiler only knows in C++ that char is smallest so every type might be casted to it.

GCC have an attribute to tell that given type may alias. It is not so easy to use it as well.

unsigned * __attribute__ ((__may_alias__)) pu = (unsigned *) &t;
if (*pu == 0xsomereservedvalue)
  do_something ();
else
  do_something_else ();

But here things at least make sense. We are asking for aliasable pointer. Cost: code is not portable now.

So after all considerations, I recommend just supply -fno-strict-aliasing option if you really sure that you are know what you do.

Konstantin Vladimirov
  • 6,791
  • 1
  • 27
  • 36
  • So you recommend to disable the compiler warning globally instead of either `reinterpret_cast` or code refactoring (e.g. the use of a `union`) at the point of interest? Not sure I can agree with that... – DevSolar Sep 09 '14 at 14:08
  • May be code refactoring is good idea. Usage of reinterpret_cast here would not help at all. Try to write something with it. – Konstantin Vladimirov Sep 09 '14 at 14:12
  • interestingly the -fno-strict-aliasing option does generate an executable that's a tiny bit smaller, even for gcc3.4 It does affect the binary. – camelccc Sep 09 '14 at 14:14
  • Yes of course. Compiler spends some instructions, padding, etc, trying to rearrange code in strict-aliasing way. This option not only removes warning it instructs compiler not to care about aliasing at all – Konstantin Vladimirov Sep 09 '14 at 14:25
  • 1
    The -fno-strict-aliasing option tells the compiler that you might be aliasing types and therefore, the compiler is no longer allowed to make any assumptions about aliasing when generating code. – doron Sep 09 '14 at 16:14
1

The “dereferencing type-punned pointer will break strict aliasing” tells you that the compiler may be making optimizations that may break your code.

The reason why this might happen is that the compiler is allowed (according to the language spec) to assume that that you will only access an array with its own type or a char type.

To a guarantee of correctness one must -either use memcpy when type punning or build with strict aliasing disabled. (Unions are a bit unclear)

Take a look here for another more detailed posting on strict aliasing.

Community
  • 1
  • 1
doron
  • 27,972
  • 12
  • 65
  • 103