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