Packing MESS

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • QbProg

    #1

    Packing MESS

    Hello,
    what I'm saying here is about VS 2005 WITHOUT service pack.

    I have two DLL projects, with EXACTLY the same project preferences and
    settings. Both have alignment set to "default", it should be 8.

    Surpise number one:
    In project B I include a file of project A in this way
    #include <FILE_FROM_A. h>

    it generates classes inside the include with an alignment of "1", but
    only in project B . I've checked everything, I don't change it with
    #pragma pack anywhere.

    The code (in project B)
    #pragma pack(show)
    #include <FILE_FROM_A. h>

    displays a warning similar to "Pragma pack = 1"
    even if I set it to 8 explicitly from the project settings.

    Surprise number two:
    #pragma pack(8)
    #include <FILE_FROM_A. h>

    if I insert into FILE_FROM_A.h the line
    #pragma pack(show)

    When I compile project A it shows me 8. Else it shows me 1 anyway !!!

    Surprise number three:
    When I finally get it to work by explicitly setting packing into each
    file with #pragma pack, it works (the classes have the same aligment),
    but the class is 4 bytes larger in project A that in project B. I
    repeat: SAME preprocessor definitions, SAME project settings.

    I spent one hour realizing that was an aligment problem :)
    Someone had similar issues?

    QbProg

  • Tamas Demjen

    #2
    Re: Packing MESS

    QbProg wrote:
    #pragma pack(8)
    #include <FILE_FROM_A. h>
    >
    if I insert into FILE_FROM_A.h the line
    #pragma pack(show)
    >
    When I compile project A it shows me 8. Else it shows me 1 anyway !!!
    Then one of your include files is clearly changing the alignment and not
    resetting it back. Everyone who explicitly modifies packing should use
    the following pattern:

    #pragma pack(push,N)
    // modify and save
    struct C
    {
    ....
    };
    #pragma pack(pop)
    //restore!!!

    Mayb it's a 3rd party header file that causes the problem. You have to
    find which one it is, and modify it to use the push and pop concept.
    Surprise number three:
    When I finally get it to work by explicitly setting packing into each
    file with #pragma pack, it works (the classes have the same aligment),
    but the class is 4 bytes larger in project A that in project B. I
    repeat: SAME preprocessor definitions, SAME project settings.
    Are you using VS2005 exclusively, or are you mixing compilers?

    You must be overlooking one #pragma push or one #define. If two classes
    don't have the same size, that's due to something being different.

    It's not enough to ensure that alignment for your class is correct, you
    also have to make sure that the alignment of all members are matching too:

    Example:

    #pragma pack(push,1)
    struct A
    {
    char c;
    int i;
    };
    #pragma pack(pop)

    #pragma pack(push,8)
    struct B
    {
    A a;
    };
    #pragma pack(pop)

    Despite the alignment for "B" is explicitly set to 8, its member "a" is
    still aligned to 1. "A" may be coming from somewhere else, which you
    might have overlooked.

    Or you have conditions in the header file:

    struct B
    {
    #ifndef NDEBUG
    int only_for_debugg ing;
    #endif
    ...
    };

    It's easy to overlook such a thing. This happened to me, when my DLL was
    in release mode and the executable in debug, and the header file
    contained an NDEBUG conditional.

    Maybe you could use the offsetof macro to check which exact member
    causes the mismatch.

    Tom

    Comment

    Working...