pack
Задает выравнивание упаковки для членов структуры, объединения и класса.
#pragma pack( [ show ] | [ push | pop ] [, identifier ] , n )
Заметки
Директива pack обеспечивает контроль на уровне объявления данных. В этом состоит отличие от параметра компилятора /Zp, который предоставляет контроль только на уровне модуля. Директива pack действует на первое объявление struct, union или class после этой директивы #pragma. Директива pack не действует на определения. При вызове директивы pack без аргументов для параметра n задается значение, указанное в параметре компилятора /Zp. Если этот параметр компилятора не указан, по умолчанию используется значение 8.
При изменении выравнивания структуры она может занимать меньше места в памяти, но возможно снижение производительности или даже возникновение аппаратного исключения для невыровненного доступа. Поведение этого исключения можно изменить с помощью директивы SetErrorMode.
show(необязательно)
Отображает текущее байтовое значение выравнивания упаковки. Значение отображается в предупреждении.push(необязательно)
Помещает текущее значение выравнивания упаковки во внутренний стек компилятора и задает для текущего выравнивания упаковки значение n. Если значение n не указано, текущее значение выравнивания упаковки не помещается в стек.pop(необязательно)
Удаляет запись из вершины внутреннего стека компилятора. Если значение n не указано вместе с pop, то новым значением выравнивания упаковки становится значение упаковки, связанное с результирующей записью в вершине стека. Если значение n указано (например, #pragma pack(pop, 16)), n становится новым значением выравнивания упаковки. Если извлечение из стека производится вместе с идентификатором identifier (например, #pragma pack(pop, r1)), из стека извлекаются все записи, пока не будет найдена запись identifier. Эта запись извлекается из стека, и новым значением выравнивания упаковки становится значение упаковки, связанное с результирующей записью в вершине стека. Если при извлечении из стека с идентификатором identifier этот идентификатор не найден ни в одной из записей стека, директива pop игнорируется.identifier(необязательно)
При использовании с директивой push присваивает имя записи во внутреннем стеке компилятора. При использовании с директивой pop записи из внутреннего стека извлекаются до тех пор, пока не будет удален идентификатор identifier; если идентификатор identifier во внутреннем стеке не найден, ничего не извлекается.n (необязательно)
Указывает значение (в байтах), используемое для упаковки. Если для модуля не задан параметр компилятора /Zp, по умолчанию для n используется значение 8. Допустимые значения: 1, 2, 4, 8 и 16. Выравнивание члена будет производиться по границе, кратной значению n или кратной размеру члена, в зависимости от того, какое из значений меньше.
Значение #pragma pack(pop, identifier, n) не определено.
Дополнительные сведения об изменении выравнивания см. в следующих разделах:
Пример
В следующем примере показано, как использовать директиву #pragma pack для изменения выравнивания структуры.
// pragma_directives_pack.cpp
#include <stddef.h>
#include <stdio.h>
struct S {
int i; // size 4
short j; // size 2
double k; // size 8
};
#pragma pack(2)
struct T {
int i;
short j;
double k;
};
int main() {
printf("%Iu ", offsetof(S, i));
printf("%Iu ", offsetof(S, j));
printf("%Iu\n", offsetof(S, k));
printf("%Iu ", offsetof(T, i));
printf("%Iu ", offsetof(T, j));
printf("%Iu\n", offsetof(T, k));
}
0 4 8
0 4 6
В следующем образце кода показано использование синтаксиса push, pop и show.
// pragma_directives_pack_2.cpp
// compile with: /W1 /c
#pragma pack() // n defaults to 8; equivalent to /Zp8
#pragma pack(show) // C4810
#pragma pack(4) // n = 4
#pragma pack(show) // C4810
#pragma pack(push, r1, 16) // n = 16, pushed to stack
#pragma pack(show) // C4810
#pragma pack(pop, r1, 2) // n = 2 , stack popped
#pragma pack(show) // C4810