Search code examples
c++clinuxg++solaris

Difference in struct sizes when #pragma pack(1) is used on Solaris and Linux


I am finding difference in struct size between Solaris and Linux when #pragma pack(1) is used. On Linux Derv is of size 128, but on Solaris it is of size 132. Could someone tell me why that is the case? How can I get it to 128 on Solaris? Below is the code:

#include <inttypes.h>
#include <iostream>
#include <stddef.h>

#pragma pack(1)
struct Base {
    char          m_1;
    uint8_t       m_2;
    uint64_t      m_3;
    uint64_t      m_4;
    uint16_t      m_5;
    uint32_t      m_6;
    uint32_t      m_7;
    uint64_t      m_8;
    uint64_t      m_9;
    uint32_t      m_10;
    char          m_11[6];
};

struct Derv : Base {
    int          m_1;
    char         m_2[66];
    int          m_3;
};
#pragma pack()

int main()
{
    std::cout << sizeof(Base) << ", " << sizeof(Derv) << std::endl;
    std::cout << offsetof(struct Derv, m_1)
              << ", " << offsetof(struct Derv, m_2)
              << ", " << offsetof(struct Derv, m_3)
              << std::endl;
}

Compiled like this: On Linux: g++ -Wno-invalid-offsetof struct_test.cpp On Solaris: CC -g0 -xarch=sse2 -mt struct_test.cpp

Versions:

$ g++ -v

Using built-in specs. Target: x86_64-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux Thread model: posix gcc version 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC)

Solaris compiler:

$ CC -V

CC: Sun C++ 5.9 SunOS_i386 Patch 124864-13 2009/05/26

Thanks for your time.


Solution

  • Pragma pack doesn't guarantee there will be no spaces; at best it means the compiler will pack stuff as much as it can. My suggestion is to re-order the items in your struct from largest to smallest; although there's no guarantee (pragmas are, by definition, implementation dependent,) empirically, that usually will get rid of the 'holes' in your structure packing.

    There may be other compiler flags that you can use, but if you don't care about the order of items in your struct, ordering from largest to smallest usually does the trick in a more portable(-ish) way.

    (obviously this isn't always an option - e.g. if you're trying to full in a structure that goes over the wire or gets passed to some API. But it works for internal storage)