15471 – [3.4/4.0 Regression] Incorrect member pointer offsets in anonymous structs/unions (original) (raw)

| Description Udo Steinberg 2004-05-15 21:39:47 UTC The code below outputs the addresses of member variables of class "myclass" using a table of pointers to member variables and using an instance of "myclass". I'd expect both methods to produce the same result, however, the addresses of member variables x and y are wrong when applying the member pointers to object "foo". Compiler version: Reading specs from /usr/lib/gcc/i486-slackware-linux/3.4.0/specs Configured with: ../gcc-3.4.0/configure --prefix=/usr --enable-shared --enable-threads=posix --enable-__cxa_atexit --disable-checking --with-gnu-ld --verbose --target=i486-slackware-linux --host=i486-slackware-linux Thread model: posix gcc version 3.4.0 Example code to demonstrate the problem: #include <stdio.h> class myclass { public: union { unsigned state[5]; struct { unsigned a; unsigned b; union { unsigned nums[2]; struct { unsigned x, y; }; }; unsigned c; }; }; }; unsigned myclass::* members[] = { &myclass::a, &myclass::b, &myclass::x, &myclass::y, &myclass::c, }; myclass foo; int main (void) { printf ("a -> %p %p\n", &(foo.*members[0]), &foo.a); printf ("b -> %p %p\n", &(foo.*members[1]), &foo.b); printf ("x -> %p %p\n", &(foo.*members[2]), &foo.x); // differs printf ("y -> %p %p\n", &(foo.*members[3]), &foo.y); // differs printf ("c -> %p %p\n", &(foo.*members[4]), &foo.c); return 0; } Comment 1 Drea Pinski 2004-05-15 21:56:59 UTC anonymous structs are an extension to c++ so they could act any way. Comment 2 Wolfgang Bangerth 2004-05-25 14:20:55 UTC I don't know what we're supposed to do here, but this is indeed surprising: ----------------------- #include <stdio.h> struct myclass { unsigned a; union { unsigned x; }; }; int main () { myclass foo; unsigned myclass::* member = &myclass::x; printf ("x -> %p %p\n", &(foo.*member), &foo.x); } ----------------------- One would expect the two pointers to be the same, but they're not: g/x> /home/bangerth/bin/gcc-3.4-pre/bin/c++ x.cc ; ./a.out x -> 0xbfffeaa0 0xbfffeaa4 It has indeed to do with the anonymous union (which in this case only contains a single element), since if I remove it and bring the variable x to the myclass scope, then the problem disappears. W. Comment 3 Giovanni Bajo 2004-05-26 12:07:51 UTC I couldn't find the relevant paragraph in the standard, thus I am not sure this is actually legal code. It must be noted that EDG in strict mode accepts it and generates the same address for both pointers (which is by no doubt the correct behaviour, once we assume the code is legal). GCC rejects this snippet up to 3.4. Since 3.4, we accept the snippet but generate wrong code with it. I rate this as a regression nonetheless, since wrong-code is much worse than what we used to do. Comment 8 Mark Mitchell 2004-05-28 23:35:50 UTC Fixed in GCC 3.4.1. | | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | |