sizeof란 무엇일까?
C언어에서 sizeof() 연산자는 피연산자의 크기를 바이트 단위로 반환하는 기능을 가지고 있습니다.
1. sizeof 의 사용법
(1) 피연산자가 데이터 타입일 경우
size_t size_char = sizeof(char); // 1
size_t size_int = sizeof(int); // 4
size_t size_float = sizeof(float); // 4
size_t size_double = sizeof(double); // 8
C
복사
(2) 피연산자가 표현식 일때
int a = 10;
double d = 10.24;
size_t size = sizeof(a + d); // 8
C
복사
해당 코드에서는 8이 저장되게 됩니다.
a + d 연산 처리시 타입이 큰 double로 형변환이 되기 때문입니다.
2. sizeof 처리 과정
sizeof는 컴파일 시간에 처리되는 경우가 있고, 런타임 시간에 처리되는 경우가 있다.
(1) 컴파일 시간 처리
#include <stdio.h>
#include <stddef.h>
int main()
{
int i = 10;
size_t size = sizeof(i++);
printf("size of i : %lu\n", (long unsigned ) size); // 4
printf("value of i : %d\n", i); // 10
return 0;
}
C
복사
해당 코드에서는 4, 10이 출력되게 됩니다. i++ 의 증감 연산자는 적용되지 않습니다.
그 이유는 컴파일시에 i++를 바이트 숫자인 4로 변경되기 때문입니다.
해당 코드를 어셈블리어로 살펴보면
size_t size = sizeof(i++);
movl $0x4, 0x1c
C
복사
0x1c는 size의 메모리 주소고, 0x4가 i++로 컴파일시에 값이 변경되어서 처리 됩니다.
i++의 증감 연산자는 처리되지 않게 됩니다.
(2) 런타임 시간 처리
sizeof는 컴파일 시간에 처리가 되는 경우도 있지만, 런타임시에 처리되는 경우도 있습니다.
가변 배열 길이를 계산할때 sizeof는 런타임시에 처리가 됩니다.
#include <stdio.h>
#include <stddef.h>
int main()
{
unsigned int size;
size_t array_size;
printf("Enter the size:");
scanf("%u", &size);
int array[size];
array_size = sizeof(array);
printf("Size of array : %lu\n", (long unsigned ) array_size);
return 0;
}
C
복사
해당 코드는 scanf로 배열의 길이를 입력받고, 배열을 할당합니다.
어셈블리로 확인해보겠습니다.
array_size = sizeof(array);
mov %ecx, %eax
shl $0x2, $eax
mov %eax, -0x1c
C
복사
컴파일 시간에 처리하는 sizeof와 차이점이 있습니다.
가변 길이 배열의 sizeof 계산의 경우에 해당 배열의 주소값에서 입력받은 size를 빼면서 처리를 합니다.
(죄송합니다.. 이 어셈블리 코드는 제대로 이해를 못했습니다. 확실한건 가변길이의 배열의 경우에는 런타임시에 처리된다는 것입니다.)
3. sizeof 구현해보기
sizeof를 직접 구현해보는 식으로 sizeof를 더 깊게 이해 해볼 수 있을거 같습니다.
#define SIZEOF(object) (char *)(&object+1) - (char *)(&object)
C
복사
간단하게 매크로로 sizeof를 구현할 수 있습니다.
포인터에 더하기 연산을 처리하면, 그 요소의 크기만큼 더하기 연산이 됩니다.
더하기 + 1 이후에 원본 포인터 값을 빼면, 해당 object의 바이트 크기가 계산이 됩니다.
참고 문헌