Frage

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.

War es hilfreich?

Lösung 2

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)

Andere Tipps

The Sun C++ compiler understands that pragma slightly differently. You also need to pass it the option -misalign in order for it to allow smaller then default alignment.

Refer to Sun Studio 12: C++ User's Guide for more details.

Oracle Solaris Studio 12.3 C Compiler version 5.12

$ > man cc

... 
 -misalign
       (SPARC) Obsolete. You should not use this option. Use
       the -xmemalign=1i option instead. For a complete list
       of obsolete options and flags, see the C User's Guide.

So, on Oracle Solaris Studio 12.3 with C compiler, you should use

-xmemalign=1i, not -misalign

And, see also Oracle Solaris Studio 12.3 : C User's Guide : 2.11.19 #pragma pack http://docs.oracle.com/cd/E24457_01/html/E21990/bjaby.html#indexterm-96

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top