C와 C++에서는 정수형 데이터를 처리하기 위해 short, int, long, long long 네 가지 데이터 타입을 제공합니다. 각 타입은 서로 다른 크기의 메모리 공간을 차지하며, 그 크기는 CPU 아키텍처와 운영체제, 심지어 컴파일러에 따라서도 달라질 수 있습니다.
예를 들어 int 타입은 어떤 시스템에서는 4바이트, 어떤 시스템에서는 2바이트를 차지하기도 합니다. 이러한 차이는 크로스 컴파일러(cross compiler)를 사용할 때 특히 두드러집니다. 크로스 컴파일러란 현재 개발 환경과 다른 플랫폼을 대상으로 코드를 컴파일할 수 있는 컴파일러를 의미합니다.
다음 코드를 32비트 시스템과 64비트 시스템에서 각각 컴파일하여 실행하면 서로 다른 결과가 출력됩니다.
예제 코드
#include<stdio.h>
int main() {
printf("Size of int : %ld Bytes\n", sizeof(int));
printf("Size of long : %ld Bytes\n", sizeof(long));
printf("Size of long long : %ld Bytes", sizeof(long long));
}
32비트 시스템 출력 결과
Size of int : 4 Bytes
Size of long : 4 Bytes
Size of long long : 8 Bytes
64비트 시스템 출력 결과
Size of int : 4 Bytes
Size of long : 8 Bytes
Size of long long : 8 Bytes
실행 결과에서 확인할 수 있듯이, long 타입의 크기는 컴파일 환경에 따라 4바이트 또는 8바이트로 달라집니다. 그렇다면 이러한 차이가 발생하는 근본적인 이유는 무엇일까요?
데이터 버스와 CPU 레지스터의 관계
CPU는 메모리 주소 레지스터(MAR, Memory Address Register)에 주소를 지정하여 주기억장치(RAM)에서 데이터를 호출합니다. 원하는 위치를 찾으면 해당 데이터는 메모리 버퍼 레지스터(MBR, Memory Buffer Register)로 전송되고, 이후 연산에 사용하기 위해 CPU 레지스터에 저장됩니다.
이 과정에서 데이터 버스(data bus)의 폭이 CPU 레지스터의 크기를 결정하게 됩니다. 32비트 시스템은 한 번의 사이클에 최대 4바이트(32비트)의 데이터만 호출할 수 있으며, 이보다 큰 데이터를 처리하려면 두 번의 사이클이 필요합니다. 따라서 작은 크기의 데이터를 다룰 때는 이러한 차이가 실제 성능에 큰 영향을 미치지 않습니다.