[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now


Why Pragma Pack

Posted on 2004-09-03
Medium Priority
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 1000 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

[Webinar] Lessons on Recovering from Petya

Skyport is working hard to help customers recover from recent attacks, like the Petya worm. This work has brought to light some important lessons. New malware attacks like this can take down your entire environment. Learn from others mistakes on how to prevent Petya like worms.

Question has a verified solution.

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

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

656 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