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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux