C++ #pragma pack: Memory Alignment Guide

about 5 years ago

C++ #pragma pack: Memory Alignment Guide

#Why using #pragma pack?

The directive #pragma pack is used to change the current packing alignment value on the internal compiler stack. The packing alignment affects how data is being stored inside a structure, union, or a class.

#Using different packing values for two structures

In order to show the effect of the pragma pack, let’s consider the following code:

#include <iostream>
#include <type_traits>

// No pragma pack directive is being used for struct A
struct A
{
    char c;
    int n;
    double d;
};

#pragma pack(push,1)
struct B
{
    char c;
    int n;
    double d;
};
#pragma pack(pop)

int main()
{
    A foo;
    B bar;
    // Let's store the same data for "foo" and "bar"
    foo.c = 'A';
    foo.n = 0x12345678;
    foo.d = 0.89898989;
    bar.c = 'A';
    bar.n = 0x12345678;
    bar.d = 0.89898989;
    std::cout << "alignment_of<A>: " << std::alignment_of<A>::value << std::endl;
    std::cout << "alignment_of<B>: " << std::alignment_of<B>::value << std::endl;
    std::cout << "sizeof(A): " << sizeof(foo) << std::endl;
    std::cout << "sizeof(B): " << sizeof(bar) << std::endl;
    // code to print data stored in "foo" and "bar" structures
}

Which is the effect of the directives #pragma pack(push,1) on the structure of type “B”? Which is the effect of #pragma pack(pop)?

As explained in the Microsoft documentation, #pragma can be used to push or to pop the current packing alignment value on the internal compiler stack.

In the example above, the compiler uses the one byte packing for B. A different value n can be chosen too. The permitted values for n are: 1, 2, 4, 8 and 16.

If this directive is not specified, then the compiler builds the code using the default packing alignment.

#Quick question for you!

If the explanation is clear, which is then the expected output of the code in the example above?
If we run the code, then the following text is printed on the console:
alignment_of<A>: 8
alignment_of<B>: 1
sizeof(A): 16
sizeof(B): 13
The compiler is using 8 bytes packing for the structure “foo” and, as requested, the 1 byte packing for the structure “bar”.

The effect of and #pragma pack(pop) is to restore the default compiler packing for the code following the declaration of the structure B.

If the memory data values are printed for both “foo” and “bar”, which values are expected to be printed?
Please, find the console output here below:
foo: 41 cc cc cc 78 56 34 12 26 82 1f 72 86 c4 ec 3f     // 8 byte packing
    ^-----------------------^-----------------------^
bar: 41 78 56 34 12 26 82 1f 72 86 c4 ec 3f              // 1 byte packing
    ^--^--^--^--^--^--^--^--^--^--^--^--^--^

As you can see, 3 bytes in the structure “foo” are completely unused. The value of these unused memory location is set to 0xcc.

Instead, for the second variable that occupies only 13 bytes, there are no unused memory locations.

#Pro and cons

The usage of the #pragma pack directive reduces the amount of memory used to store data inside structures, union, …

Unfortunately, as side effect, a decrease in performance or also a hardware-generated exception for unaligned access might occur. In order to handle these exceptions, the function SetErrorMode() should be called with the input mode parameter equal to SEM_NOALIGNMENTFAULTEXCEPT.

Enjoyed "C++ #pragma pack: Memory Alignment Guide"? Get more like this!

Get practical programming tips, algorithm explanations, and tech insights delivered weekly. No spam, just valuable content.

✓ No spam ever✓ Unsubscribe anytime✓ Privacy protected