A member variable of a class that utilizes EBO and has a type that also utilizes EBO appears to be laid out at the wrong offset.
In the example below, the only difference between the classes Good and Bad is that the member of Bad inherits from a class with no members. The sizeof printouts show that EBO is in play, but the Bad class gets an extra four byte padding before the member. There's no reason Bad should be any larger than Good. Kind Regards /David #include <cstdio> struct Empty { }; struct Member { int extent; }; struct MemberWithEBO : public Empty { int extent; }; struct Good : public Empty { Member m; }; // OK struct Bad : public Empty { MemberWithEBO m; }; // Broken, see below #define PRINT(x) printf ("%-25s %d\n", # x ":", (x)) template <typename C, typename T> long int offsetOf (T C::*m) { C proto; return (long int)(void*)&(proto.*m) - (long int)(void *)&proto; } int main (int argc, char ** argv) { PRINT (sizeof (Member)); PRINT (sizeof (Good)); PRINT (offsetOf (&Good::m)); PRINT (sizeof (MemberWithEBO)); PRINT (sizeof (Bad)); PRINT (offsetOf (&Bad::m)); } // Printout: // // sizeof (Member): 4 // sizeof (Good): 4 // offsetOf (&Good::m): 0 // sizeof (MemberWithEBO): 4 // sizeof (Bad): 8 <-- Should be 4 // offsetOf (&Bad::m): 4 <-- Should be 0 > g++ -v -save-temps ebo_bug.cc Using built-in specs. Target: x86_64-unknown-linux-gnu Configured with: ../configure --prefix=/usr/local/gcc431 --with-pkgversion=gcc431 --enable-languages=c,c++ Thread model: posix gcc version 4.3.1 (gcc431) COLLECT_GCC_OPTIONS='-v' '-save-temps' '-shared-libgcc' '-mtune=generic' /usr/local/gcc431/libexec/gcc/x86_64-unknown-linux-gnu/4.3.1/cc1plus -E -quiet -v -D_GNU_SOURCE ebo_bug.cc -mtune=generic -fpch-preprocess -o ebo_bug.ii ignoring nonexistent directory "/usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/../../../../x86_64-unknown-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/../../../../include/c++/4.3.1 /usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/../../../../include/c++/4.3.1/x86_64-unknown-linux-gnu /usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/../../../../include/c++/4.3.1/backward /usr/local/include /usr/local/gcc431/include /usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/include /usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/include-fixed /usr/include End of search list. COLLECT_GCC_OPTIONS='-v' '-save-temps' '-shared-libgcc' '-mtune=generic' /usr/local/gcc431/libexec/gcc/x86_64-unknown-linux-gnu/4.3.1/cc1plus -fpreprocessed ebo_bug.ii -quiet -dumpbase ebo_bug.cc -mtune=generic -auxbase ebo_bug -version -o ebo_bug.s GNU C++ (gcc431) version 4.3.1 (x86_64-unknown-linux-gnu) compiled by GNU C version 4.3.1, GMP version 4.1.4, MPFR version 2.2.1. GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: 4926fc16e15403c044148a60354159ba COLLECT_GCC_OPTIONS='-v' '-save-temps' '-shared-libgcc' '-mtune=generic' as -V -Qy -o ebo_bug.o ebo_bug.s GNU assembler version 2.17.50.0.6-6.el5 (x86_64-redhat-linux) using BFD version 2.17.50.0.6-6.el5 20061020 COMPILER_PATH=/usr/local/gcc431/libexec/gcc/x86_64-unknown-linux-gnu/4.3.1/:/usr/local/gcc431/libexec/gcc/x86_64-unknown-linux-gnu/4.3.1/:/usr/local/gcc431/libexec/gcc/x86_64-unknown-linux-gnu/:/usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/:/usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/ LIBRARY_PATH=/usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/:/usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-v' '-save-temps' '-shared-libgcc' '-mtune=generic' /usr/local/gcc431/libexec/gcc/x86_64-unknown-linux-gnu/4.3.1/collect2 --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/../lib64/crt1.o /usr/lib/../lib64/crti.o /usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/crtbegin.o -L/usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1 -L/usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/../../.. ebo_bug.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/crtend.o /usr/lib/../lib64/crtn.o -- Summary: Member variable of empty base optimized (EBO) class appears on wrong offset Product: gcc Version: 4.3.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: david dot rosenborg at pantor dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37762