- char, short, int, long의 크기
sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)
대부분 1, 2, 4, 4가 나오며 DOS 때의 16비트 컴파일러는 1, 2, 2, 4 였던 것 같다.
64비트 컴파일러는 sizeof(int)를 원래의 의미에 맞게 8로 정의하는 것도 있으나 호환성을 위해 4로 정의 하는 것이 더 많은 것 같다.
- bool의 크기
1 <= sizeof(bool) <= sizeof(long)
VC++이나 gcc는 1이지만, ARM용 컴파일러는 4이다.
구조체 중간에 bool이 있다면 그 구조체의 크기는 예측하기가 어렵다. 특히 그 크기가 1이라면 bool이 있는 구조체 내의 위치에 따라 alignment의 영향을 받아 그 크기가 달라진다.
- wchar_t의 크기
sizeof(char) <= sizeof(wchar_t) <= sizeof(long)
UCS-2가 기본인 VC++은 2, UCS-4가 기본인 gcc는 4이다. 컴파일 옵션에 따라서 변경도 가능하다.
그리고 이것 때문에 L””로 만든 문자열의 크기도 달라진다.
- float과 double의 크기
sizeof(float) <= sizeof(double) <= sizeof(long double)
VC++에서는 각각 4, 8, 8으로 알고 있지만 다른 컴파일러에서는 확인 해 본 적은 없다.
- signed / unsigned에 따른 크기
sizeof(N) <= sizeof(signed N) <= sizeof(unsigned N)
2의 보수로서 음수를 표현하는 것이면 항상 모두 같아야 하는 것이 아닌가 생각되긴 하지만… 이건 잘 모르겠다.
- enum의 크기
보통 4로 고정되기도 하지만 ARM용 컴파일러는 최대 값에 따라 그 크기가 달라진다.
따라서 구조체 내에 enum으로 선언된 변수가 있으면 enum의 항목 추가에 따라 어느 순간 그 구조체의 크기가 달라질 수 있다는 것이다. 따라서 항상 제일 마지막 값에는 0x7FFFFFFF를 강제로 넣어 주는 것이 이 문제를 피할 수 있는 한 방법이 된다.
- char의 선언
일반적인 컴파일러는 char로 변수 선언을 하게 되면 당연히 signed가 생략된 것으로 보지만 ARM 계열의 컴파일러에서는 unsigned가 생략된 것으로 취급하는 것이 default 동작이다. 이것은 char를 더 큰 자료형으로 (자동)확장하여 연산하는 경우 찾기 어려운 오류를 만든다.
이 때는 직접 signed로 선언해 주는 방법도 있지만 컴파일 옵션에서 일괄 적용하는 것이 맞을 듯 하다. (ARM 컴파일러의 매뉴얼에 보면 unsigned를 default로 하는 이유가 나와 있다)
Posted by 안영기