Why Pragma Pack

Posted on 2004-09-03
Last Modified: 2011-09-20
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.
Question by:alanpong
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
LVL 13

Accepted Solution

SteH earned 250 total points
ID: 11972229
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).
LVL 22

Expert Comment

ID: 11972492
#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.

Expert Comment

ID: 11973608
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.
LVL 19

Expert Comment

ID: 11983015
>> 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.

Author Comment

ID: 12023842
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

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

688 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question