Packing MESS

  • Thread starter Thread starter QbProg
  • Start date Start date
Q

QbProg

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
 
QbProg said:
#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_debugging;
#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
 
Back
Top