[Webinar] Learn how to a build a cloud-first strategyRegister Now

  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 698
  • Last Modified:

Why Pragma Pack

Dear Experts,

This is my first time to meet Pragma Pack in my life.

Say, I've the following structure:
typedef sMyStruct{
  DWORD dw1;
  WORD w;
  char mychar1[10];
  DWORD dw2;
  char mychar2[7];
  BOOL b;
  char flag;
} sMyStruct;

1. Can someone explain the function of Pragma Pack?
2. Which Pragma Pack(2,4,6,8,16,32) should be used in above example and why?
3. If I don't use Pragma Pack, what is the result?
Many many thanks.
1 Solution
In normal compilations you can define the alignment of variables which 8 bytes by default. This means that inside a struct this boundary will come into effect as well; no element will not cross a boundary but start at the next boundary instead. (Elements longer than the boundary size will cross the next obviously but not during the first x bytes.
In your struct that means for the addresses of the elements:
0:  dw1 (4 bytes)
4:  w (2 bytes)
6: padding (2 bytes)
8: mychar1 (10bytes)
18: padding (6 bytes)
24: dw2 (4bytes) // not sure thsi could be put at address 20 as well.
28: padding (4 bytes)
32: mychar2 7 bytes)
39: padding (1 byte)
40: b (4 bytes)
44: flag (1 byte)
45: padding (3 bytes)

As you can see this results in a lot of padding bytes but making access to each member efficient. To check look at &(xxx.dw1), &(xxx.w), etc. Whit pragma pack you can specify to change this alignment for that structure. The lower the number means the lower extra space is used for padding but access to a member might need more memory cycles.

Without pargam pack the projects default is used (normally 8 bytes).
#pragma pack() exists because sometimes you need your structure to have a certain internal field alignment.

If you want maximum speed, most compilers will align fields on whatever boundaries are the easiest and fasttest for the CPU to access.  This is typically 2-byte alignment on 16-bit processors, 4-byte alignment on 32-bit processors, etc...

But sometimes you really NEED a packed struct, with little or no filler bytes for alignment.  The most common reason is you're reading or writing this struct to some other program or module that expects a packed structure.  Or you're short on memory and need the smallest struct possible.

Typically it's best to write code that doesnt depend on the packing strategy.  If you are careful to reference fields individually, and use sizeof(field) as needed, it's usually possible to write code that behaves the same, no matter what the #pack setting.  On the other hand, if you do raw byte moves between fields, or typecast fields to different variable sizes, or blindly step pointers from field to field, #pack can make a huge difference in the program results.
The "best" structure member alignment varies by the architecture of the processor and has gotten bigger over time as CPUs get wider and memory gets cheaper.

You need to control struct member alignment if you are reading or writing a structure to disk or via the network, and you're using write(handle, myStruct, sizeof(myStruct)) to write the whole structure rather than doing it one field at a time, and you want the result to be compatible with some previous machine's output or you're reading some legacy file.

Structure alignment is only one problem when reading/writing legacy files. Byte order is another, and floating point format is a third. So if you're doing legacy file I/O watch out.
>> Typically it's best to write code that doesnt depend on the packing strategy

I just want to emphasize this point.  Using packed structs to do data IO (network, files, etc.) will only get you in trouble.  Sizes, byte order, data representation (boolean and float values come to mind here) and default alignment cannot be depended on.  You should write code to explicitly handle all these things.

Also, if you use #pragma pack and forget to return it to defaults appropriately, you may really mess things up.  Unless you have a really good reason (there aren't many), it's best not to use #pragma pack.
alanpongAuthor Commented:
Steh, thanks for the concept of padding and the detailed example.

grg99, thanks for the point about moving raw data in struct and typecasting the struct.

guntherothk and drichards, i'll transfer the struct through the network and thanks for the remind.

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Tackle projects and never again get stuck behind a technical roadblock.
Join Now