개요
C/C++에서 sizeof()는 데이터 타입이나 변수가 차지하는 메모리 크기를 계산하는 단항 연산자입니다. 흥미로운 점은 매크로를 활용하면 표준 sizeof()와 동일하게 동작하는 자신만의 sizeof 연산자를 직접 구현할 수 있다는 것입니다.
구현 원리
핵심 아이디어는 포인터 산술 연산을 이용하는 것입니다. 객체의 주소에 1을 더하면 해당 타입의 크기만큼 주소가 증가하는데, 이를 char*로 캐스팅한 후 두 주소의 차이를 구하면 정확히 객체의 바이트 크기가 됩니다.
#define 지시문을 사용한 구현 문법은 다음과 같습니다.
#define Any_name(object) (char *)(&object+1) - (char *)(&object)
여기서 각 요소의 의미는 다음과 같습니다.
- Any_name − 사용자가 임의로 정하는 매크로 이름으로, 자신만의 sizeof 연산자 역할을 합니다.
- (char *)(&object) − 객체의 시작 주소를 char 포인터로 변환합니다.
- (char *)(&object+1) − 다음 객체의 시작 주소를 char 포인터로 변환합니다.
주소 차이를 char 단위(1바이트)로 계산하기 때문에 결과값이 곧바로 바이트 크기가 됩니다.
예제 코드
다음은 C 언어에서 자체 sizeof 연산자를 구현하고 활용하는 예제입니다.
#include <stdio.h>
#define to_find_size(object) (char *)(&object+1) - (char *)(&object)
int main() {
int x;
char a[50];
printf("Integer size : %d\n", to_find_size(x));
printf("Character size : %d\n", to_find_size(a));
return 0;
}실행 결과
Integer size : 4 Character size : 50
코드 분석
위 프로그램에서는 #define 지시문으로 자체 sizeof 연산자인 to_find_size를 선언했습니다. 이 매크로는 int형 변수와 char형 배열의 크기를 각각 계산합니다.
#define to_find_size(object) (char *)(&object+1) - (char *)(&object)
….
int x;
char a[50];
printf("Integer size : %d\n", to_find_size(x));
printf("Character size : %d\n", to_find_size(a));int형 변수 x의 경우 일반적으로 4바이트가 출력되며, 50개의 요소를 가진 char 배열 a는 50바이트로 정확하게 계산됩니다. 이처럼 매크로 기반 구현은 기본 타입뿐 아니라 배열에 대해서도 표준 sizeof와 동일한 결과를 보여줍니다.
주의 사항
이 방식은 학습 목적이나 특수한 상황에서 유용하지만, 실제 프로덕션 코드에서는 표준 sizeof 연산자를 사용하는 것이 안전합니다. 매크로 방식은 컴파일러 최적화나 타입 검사 측면에서 표준 연산자보다 제한적일 수 있기 때문입니다.