#pragma pack
is a non-standard extension that specifies the packing alignment for structure, union, and class members.
It is useful to
- remove padding and decrease the size of objects
- align members to better fit optimal cpu alignment
However, the pragma pack directives need to be correctly defined to work properly.
This rule raises an issue if:
- the specified packing value is incorrect: it can only be 1, 2, 4, 8, or 16
- a parameter is ill-formed
- the
pop
variant of this #pragma
is called with both arguments identifier
and value
: such a
call is undefined behavior
- a
#pragma pack(push...)
is performed but there is not corresponding use of #pragma pack(pop...)
- a
#pragma pack(pop...)
is performed but there is not corresponding use of #pragma pack(push...)
- a
#pragma pack
is in effect across several files: this becomes too complex and could easily lead to undefined behavior, the same
structure having a different layout when seen from different translation units
Noncompliant code example
#pragma pack(5) // Noncompliant, value is invalid
#pragma pack(2+2) // Noncompliant, value should be a literal
#pragma pack(4)
#include "myFile.h" // Noncompliant, the specified alignment value will be applied to this file
struct T {
int i;
short j;
double k;
};
#pragma pack(push, r1, 16)
#pragma pack(pop, r1, 4) // Noncompliant, call to pop with two arguments is undefined
#pragma pack(push, r2, 16) // Noncompliant, call to push with no matching pop
#pragma pack(pop, r3) // Noncompliant, call to pop with no matching push
#pragma pack(push, 8) // Noncompliant, unmatched push
Compliant solution
#include "myFile.h"
#pragma pack(4)
struct T {
int i;
short j;
double k;
};
#pragma pack(push, r1, 16)
#pragma pack(pop, r1)
#pragma pack(push, r2, 16)
#pragma pack(pop, r2)
#pragma pack(push, 8)
#pragma pack(pop)