title: Code to reliably trigger alias errors?
body: <p>Title pretty much says it all. Can someone direct me to or provide me with some code that will reliably trigger alias errors with somewhat recent versions of gcc? The reason i am asking is that i am trying to study the effects of strict aliasing but no matter how hard i try to violate it gcc will always come up with the "correct" result making any tests on how to deal with cases where you want to break the rules pretty much useless. I am not asking about warnings (-Wstrict-aliasing=2 gives warnings on pretty much everything i do) but code that actually fails when being optimized with -fstrict-aliasing.</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdint.h&gt;
  
  typedef struct mystruct_s {
      uint32_t int1;
      uint32_t int2;
  } mystruct_t;
  
  typedef mystruct_t __attribute__( ( may_alias ) ) mystruct_alias_bad1_t;
  // warning: ignoring attributes applied to ‘struct mystruct_s’ after definition [-Wattributes]
  // so basically gcc is telling me i have to define it again if want an aliasable
  // version?
  
  typedef struct mystruct_alias_s {
      uint32_t int1;
      uint32_t int2;
  } __attribute__( ( may_alias ) ) mystruct_alias_t;
  
  static __attribute__( ( optimize( "no-strict-aliasing" ) ) ) void myfunc1_alias1( void ) {
      uint32_t var, *i = &amp;var;
      float *f = (float*)&amp;var;
      // warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
      // so __attribute__( ( optimize( "no-strict-aliasing" ) ) ) is either
      // not doing anything or gcc still gives warning even if the
      // optimization does not actually happen 
  
      *i = 100;
      printf( "[test-5] %u", var );
      *f = 0.f;
      printf( " %u (%s)\n", var, var != 100 ? "OK" : "FAIL" );
  }
  
  #pragma GCC optimize "no-strict-aliasing"
  static void myfunc1_alias2( void ) {
      uint32_t var, *i = &amp;var;
      float *f = (float*)&amp;var;
      // warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
      // this seems to be identical to the 
      // __attribute__( ( optimize( "no-strict-aliasing" ) ) ) case
  
      *i = 100;
      printf( "[test-6] %u", var );
      *f = 0.f;
      printf( " %u (%s)\n", var, var != 100 ? "OK" : "FAIL" );
  }
  #pragma GCC optimize "strict-aliasing"
  
  static void myfunc1( void ) {
      uint32_t var, *i = &amp;var;
      float *f = (float*)&amp;var;
      // warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
      // conclusion: pretty much none. all 3 functions generate exatcly the same
      // code that does just work as expected with no breakage at all despite the
      // warning so no-strict-aliasing on a per function level might do nothing
      // at all or just not for this code - no way to really tell...
  
      *i = 100;
      printf( "[test-7] %u", var );
      *f = 0.f;
      printf( " %u (%s)\n", var, var != 100 ? "OK" : "FAIL" );
  }
  
  int main( int argc, char **argv ) {
      unsigned char buf[sizeof( mystruct_t )] = { 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02 };
  
      // obvious rule violation:
      printf( "[test-1] int2 == %08X\n",
          ( (mystruct_t*)buf )-&gt;int2
          // warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
      );
      // prints: [test-1] int2 == 2020202
  
      // pretty much the same as above but avoiding the struct:
      printf( "[test-2] int1 == %08X, int2 == %08X\n",
          *(uint32_t*)buf,
          // warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
          ( (uint32_t*)buf )[1]
          // warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
          // (you need -Wstrict-aliasing=2 - just -Wstrict-aliasing is not enough)
      );
      // prints: [test-2] int1 == 1010101, int2 == 2020202
  
      // lets try telling gcc that it should respect what we are trying to do:
      printf( "[test-3] int1 == %08X, int2 == %08X\n",
          ( ( __attribute__( ( may_alias ) ) mystruct_t*)buf )-&gt;int1,
          // warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
          ( (mystruct_alias_t*)buf )-&gt;int2
          // this is the only one that works so far but it seems there is no way
          // to cast to such a pointer on the fly - you have to apply this
          // attribute to the original struct...
      );
      // prints: [test-3] int1 == 1010101, int2 == 2020202
  
      // lets try to be creative (basically make a mess with C99 anonymous arrays):
      printf( "[test-4] int1 == %08X, int2 == %08X\n",
          ( (  __attribute__( ( may_alias ) ) mystruct_t* [1] ) { (mystruct_t*)buf } )[0]-&gt;int1,
          // warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
          // (you need -Wstrict-aliasing=2 - just -Wstrict-aliasing is not enough)
          // seems the attribute is ignored just as silently as for the direct cast
          ( ( mystruct_t* [1] ) { (mystruct_t*)buf } )[0]-&gt;int2
          // warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
          // (you need -Wstrict-aliasing=2 - just -Wstrict-aliasing is not enough)
          // i guess that evades -Wstrict-aliasing since that seems to pretty
          // much seems to only warn about code that casts and dereferences in one
          // go
      );
      // prints: [test-4] int1 == 1010101, int2 == 2020202
  
      // lets try to use __attribute__ optimize to disable strict aliasing temporaly:
      myfunc1_alias1();
  
      // lets try pragma:
      // #pragma GCC optimize "-fno-strict-aliasing"
      // error: #pragma GCC optimize is not allowed inside functions
      // (at least if you uncomment that line) so lets try a function again:
      myfunc1_alias2();
  
      // lets check if compiling the function without any makeup makes a difference:
      myfunc1();
  
      return 0;
  }
  </code></pre>
  
  <p>Final edit:</p>
  
  <p>I do not really have time to update the code right now but i have tried the different approaches of avoiding strict aliasing with the code mnunberg provided with the following results:</p>
  
  <pre><code>__attribute__( ( may_alias ) )
  </code></pre>
  
  <p>Works but only when added to to the actual structure definition (does not seem to matter which one you choose) - elsewhere its silently ignored.</p>
  
  <pre><code>__attribute__( ( optimize( "no-strict-aliasing" ) ) )
  </code></pre>
  
  <p>As suspected this has no effect at all. The program still hangs.</p>
  
  <pre><code>#pragma GCC optimize "no-strict-aliasing"
  </code></pre>
  
  <p>Also as suspected this does the same as the one above (nothing). </p>