[C, C++] pragma pack 개념과 사용이유

구조체의 크기

구조체의 크기는 구조체 변수 중 크기가 가장 큰 자료형을 기준으로 배수만큼 커진다. 즉 구조체의 크기는 변수의 크기에 패딩비트(구조체 크기를 가장 큰 자료형 기준으로 배수만큼 만들어주기 위해 추가되는 비트)가 더해져서 변수보다 더 큰 구조체 크기를 가질 수 있고 이는 메모리 낭비를 초래한다. 더 자세한 내용은 아래 링크를 참고한다.

[C, C++] 구조체의 패딩비트와 크기 최적화

이렇게 구조체의 사이즈가 커지는 원흉인 패딩비트는 pragma pack으로 제거할 수 있다. 그러나 32/64비트 운영체제에선 4바이트 기준으로 데이터를 처리하는 것이 가장 빠른 속도를 가지기 때문에 pragma pack의 사용은 속도 저하의 원인이 될 수 있다.

#pragma pack

pragma는 전처리구문 중 하나로 컴파일러에게 명령을 전달한다. 컴파일러에 종속적이라서 컴파일러 따라 실행되는 명령어가 다르지만, 많이 쓰이는 gcc, microsoft는 pragma pack을 사용할 수 있다.

pragma(n)

pragma(n) 명령어는 코드 내 모든 구조체의 기준 바이트를 n으로 만든다. 때문에 만약 n을 1로 두게 되면 패딩비트가 사라지게 된다.

아래 세 코드에서 pragma pack 사용으로 test1 구조체의 크기가 달라진 것을 확인할 수 있다.

#include <stdio.h>

typedef struct test1
{
    char c;
    int i;
}test1;

int main()
{
    test1 t1;
    printf("struct size : %d\r\n", sizeof(t1)); // struct size : 8
}
#include <stdio.h>

#pragma pack(1)

typedef struct test1
{
    char c;
    int i;
}test1;

int main()
{
    test1 t1;
    printf("struct size : %d\r\n", sizeof(t1)); // struct size : 5
}
#include <stdio.h>

#pragma pack(2)

typedef struct test1
{
    char c;
    int i;
}test1;

int main()
{
    test1 t1;
    printf("struct size : %d\r\n", sizeof(t1)); // struct size : 6
}

pragma(push,n) / #pragma(pop)

pragma(push,n) 명령어는 pragma(pop) 명령어가 나오기 전까지 선언된 구조체의 기준 바이트를 n으로 만든다. 코드 내의 모든 구조체가 아닌 일부만 적용하고 싶을 때 사용한다.

아래 코드에서 pragma pack(push, 1) ~ pragma pack(pop) 사이에 있는 test2 구조체만 크기가 작아진것을 확인할 수 있다.

#include <stdio.h>

typedef struct test1
{
	char c;
	int i;
}test1;

#pragma pack(push, 1)

typedef struct test2
{
	char c;
	int i;
}test2;

#pragma pack(pop)

typedef struct test3
{
	char c;
	int i;
}test3;
int main()
{
	test1 t1;
	test2 t2;
	test3 t3;
	printf("struct size : %d\r\n", sizeof(t1)); // struct size : 8
	printf("struct size : %d\r\n", sizeof(t2)); // struct size : 5
	printf("struct size : %d\r\n", sizeof(t3)); // struct size : 8
}

Leave a Comment