Search
Duplicate

sizeof 연산자 파헤치기

간단소개
sizeof 연산자 동작을 이해해봅시다!
팔만코딩경 컨트리뷰터
ContributorNotionAccount
주제 / 분류
C
Scrap
태그
C99
9 more properties

sizeof란 무엇일까?

C언어에서 sizeof() 연산자는 피연산자의 크기를 바이트 단위로 반환하는 기능을 가지고 있습니다.
sizeof()의 리턴 타입은 size_t 이고, 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의 바이트 크기가 계산이 됩니다.
참고 문헌