Structure alignment changes when a constructor or destructor is added

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

 



The following code was compiled with g++ 4.1.2 and again with g++
4.6.2 on 64-bit Linux (more details at the end).  Note that S1 and S3
have identical data members.  S1 has a constructor defined, S3 does
not.  S2 inherits from S1 and S4 inherits from S2.  The size and
layout SHOULD be the same, but it is not as you can see from the
output.  If I comment out the constructor, and uncomment the
operator== function, the alignment becomes the same for both classes.
 While no specific defect results in the code, this unpredictable
behaviour makes it impossible to match the ABI of the OSF1 platform
that we are porting away from and there are an enormous number of
binary data files that we would like to read.

Any insight?  I’m very experienced with C++, but not quite a guru of
the highest order.  This looks like a defect to me.

<code>
#include <iostream>

using namespace std;

struct S1 {
  long a;
  char b;
  S1(){ a = 1; b = 2; };
//  bool operator==( const S1& c ) { return a==c.a && b==c.b; };
};

struct S2 : public S1 {
  char a;
};

struct S3 {
  long a;
  char b;
  bool operator==( const S1& c ) { return a==c.a && b==c.b; };
};

struct S4 : public S3 {
  char a;
};

int main() {
        S1 s1;
        S2 s2;
        S3 s3;
        S4 s4;

        cout << "Size of S1 is " << sizeof( S1 ) << endl;
        cout << "Offset of a is " << (int)((char*)&s1.a - (char*)&s1)
<< endl << endl;

        cout << "Size of S2 is " << sizeof( S2 ) << endl;
        cout << "Offset of a is " << (int)((char*)&s2.a - (char*)&s2)
<< endl << endl;

        cout << "Size of S3 is " << sizeof( S3 ) << endl;
        cout << "Offset of a is " << (int)((char*)&s3.a - (char*)&s3)
<< endl << endl;

        cout << "Size of S4 is " << sizeof( S4 ) << endl;
        cout << "Offset of a is " << (int)((char*)&s4.a - (char*)&s4)
<< endl << endl;

        return(0);
}
</code>

<output>
> g++ struct_align.cpp -Wall -Wextra -o struct_align.exe
> ./struct_align.exe
Size of S1 is 16
Offset of a is 0

Size of S2 is 16
Offset of a is 9

Size of S3 is 16
Offset of a is 0

Size of S4 is 24
Offset of a is 16
</output>

> uname -a
Linux riffraff 2.6.18-274.el5 #1 SMP Fri Jul 8 17:36:59 EDT 2011
x86_64 x86_64 x86_64 GNU/Linux

> /usr/bin/g++ -v
Using built-in specs.
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--enable-checking=release --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-libgcj-multifile
--enable-languages=c,c++,objc,obj-c++,java,fortran,ada
--enable-java-awt=gtk --disable-dssi --disable-plugin
--with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre
--with-cpu=generic --host=x86_64-redhat-linux
Thread model: posix
gcc version 4.1.2 20080704 (Red Hat 4.1.2-51)

> /usr/local/bin/g++ -v
Using built-in specs.
COLLECT_GCC=/usr/local/bin/g++
COLLECT_LTO_WRAPPER=/usr/local/gcc-4.6.2/libexec/gcc/x86_64-unknown-linux-gnu/4.6.2/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ./configure --prefix=/usr/local/gcc-4.6.2
Thread model: posix
gcc version 4.6.2 (GCC)

> ld -v
GNU ld version 2.17.50.0.6-14.el5 20061020



[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