#pragma pack(n)
키워드를 통해 프로그래머가 데이터 alignment 단위를 지정해 줄 수 있다.Visual Studio 2015 이상에서는
__alignof
__declspec( align )
키워드와 같이 msvc전용 키워드가 아닌, 컴파일러 간에 이식 가능한 표준alignas
alignof
연산자를 사용 할 수 있습니다. 그러나, C++ 표준은 packing을 처리하지 않으므로 대상 아키텍처의 word size보다 작은 align을 지정하려면#pragma pack(n)
(또는 컴파일러마다 가지는 확장 키워드)를 계속 사용해야 합니다.
#pragma pack
키워드를 지원하는 이유는 데이터 얼라인을 맞추기 위함이 맞긴 하지만, 더 정확히 말하자면 데이터 얼라인을 프로그래머가 임의로 조정하여 데이터를 "압축"하는 것을 위한 것이다.#pragma pack(8)
struct MyData {
char a;
float b;
char c;
};
int main(){
printf("%d", sizeof(MyData));
}
8바이트로 align한다는 관점에선 16바이트가 나와야 될 것 같지만 실상은 12바이트가 나온다.
#pragma pack(n)
은 "압축"을 위한 것이기 때문에 default로 지정된 4byte기준이 유저가 지정한 8byte보다 커서 4byte패딩을 진행하여 12바이트가 나오는 것이다.
__declspec(align(n))
같은 msvc전용 키워드나 alignas(n)
같은 표준 연산자를 사용하는 것이 옳다.
#pragma pack(8)
struct MyData {
char a;
float b;
char c;
};
// sizeof(MyData): 12
// alignof(MyData): 4
__declspec(align(8))
struct MyData {
char a;
float b;
char c;
};
// sizeof(MyData): 16
// alignof(MyData): 8
struct alignas(8) MyData {
char a;
float b;
char c;
};
// sizeof(MyData): 16
// alignof(MyData): 8
근데! 여기서 또 주의해야 할 점은 위 msdn설명에 나와있듯 “C++ 표준은 packing을 처리하지 않”기 때문에 #pragma pack(1)
과 같이 더 작은 사이즈로 데이터를 “압축”하는 용도에선 __declspec(align(n))
, alignas(n)
연산자가 먹히지 않는다.
#pragma pack(1)
struct MyData {
char a;
float b;
char c;
};
// sizeof(MyData): 6
// alignof(MyData): 1
__declspec(align(1))
struct MyData {
char a;
float b;
char c;
};
// sizeof(MyData): 12
// alignof(MyData): 4
struct alignas(1) MyData {
char a;
short b;
char c;
};
// default보다 더 작은 값으로 align을 진행하려 했다고 error를 던져줌
#pragma pack(n)
을 사용하고__declspec(align(n))
, alignas(n)
를 사용하자.