g++-4.0.3: program output is different when compiled with -O3 (did not happen with gcc-3.4.5)

Peter Doerfler gcc@pdoerfler.com
Wed May 17 14:06:00 GMT 2006


Peter Doerfler wrote:
> Erik wrote:
>> Peter Doerfler wrote:
>>> Why don't you use an anonymous union, like so?
>>
>> This is exactly what I was looking for. It seems to work great. Many 
>> thanks! Why did I not use it? I was just not smart enough.  I tried to 
>> use a union like
>>
>> union T {
>>   Coords c;
>>   Uint32 i;
>> };
>>
>> in the ordering functor, but I had to ditch that idea because it was 
>> not allowed to have a type with constructor in a union. (And Coords 
>> has a constructor, although it was omitted in the sample code here.)
>>
>>> struct Coords {
>>>
>>>   bool operator<(const Coords other) const;
>>>
>>>   union {
>>>     struct {
>>>       int x : 16, y : 16;
>>>     };
>>>
>>>     unsigned int z;
>>>   };
>>> };
>>>
>>> bool Coords::operator<(const Coords other) const {
>>>   return z < other.z;
>>> }
> 
> I just double checked with -Wall -Wextra -pedantic and it says
> error: ISO C++ prohibits anonymous structs
> 
> which seemingly doesn't mean that it doesn't work. Something similar is 
> in our production code. But the Standard is always right, so...
> 
> Here is a new version which has the advantage of hiding some 
> implementation details. You lose the bitfield initialization though.
> I'm not sure whether the compiler is required to keep struct bar members 
> in a 32bit block now, I guess you need something like 
> __attribute__(packed), but I have no idea about those. On the other hand 
> the union should force this.
> Maybe somebody can clarify although we're getting a bit off topic here.
> Anyway this compiles without warnings under -Wall -Wextra -pedantic 
> -ansi and Comeau++ is also happy.
> 
> 
> class foo {
> public:
>   typedef unsigned short int16;
> 
> private:
>   struct bar {
>     int16 x;
>     int16 y;
>   };
> 
>   union {
> 
>     bar b;
> 
>     unsigned int z;
>   };
> 
> public:
>   foo() : x(b.x), y(b.y) {}
>   foo(int16 xx, int16 yy) : x(b.x), y(b.y) {x=xx; y=yy;}
> 
>   bool operator<(const foo& other) {return z<other.z;}
> 
>   int16& x;
>   int16& y;
> 
> };
> 
> int main () {
> 
>   foo f;
>   f.x = 1; f.y=0;
>   foo g(0,1);
> 
>   return f<g;
> }
> 
> 
> Best, Peter

Never mind this approach. Now sizeof(foo) is 12 instead of 4 as it was 
before, which is probably not acceptable for most applications. I guess 
it's either compile without strict compliance or use the __extension__ 
workaround and make sure all the compilers you want to use on your code 
know what to do. Such a thing as an anonymous struct simply doesn't seem 
to exist in the Standard.

I guess further help should rather be sought at comp.lang.c++ etc.

Best, Peter



More information about the Gcc-help mailing list