프로그래밍 언어/C & C++

[c/c++] int8_t, uint8_t, int16_t, uint16_t ?

hanyoungyoo 2021. 3. 10. 17:38

c언어를 배우면 보통 primitive type 이라고 하여 short, int, long, char, float, double 등의 자료형을 배웁니다. 그런데, 소스코드를 살펴보다 보면 int8_t, uint8_t, int16_t, uint16_t ... 등을 사용하는 것을 심심치 않게 볼 수 있습니다. 

 

이런 자료형들은 <stdint.h> 라는 헤더에 정의가 되어 있는데요, 어떤 자료형인지, 왜 쓰는지를 알아 보려고 합니다.

 

1. int8_t, uint8_t, int16_t, uint16_t ... 등은 어떤 자료형인가요?

일단 해당 자료형의 정의가 된 헤더파일의 소스코드는 아래의 링크에서 확인할 수 있습니다.

sites.uclouvain.be/SystInfo/usr/include/stdint.h.html

 

stdint.h

 

sites.uclouvain.be

stdint.h 헤더파일에 int*_t의 자료형의 경우 아래와 같이 정의 된 것을 볼 수 있죠.

#ifndef __int8_t_defined
# define __int8_t_defined
typedef signed char		int8_t;
typedef short int		int16_t;
typedef int				int32_t;
# if __WORDSIZE == 64
typedef long int		int64_t;
# else
__extension__
typedef long long int	int64_t;
# endif
#endif

* #ifndef, #define, #if, #else는 여기서 설명을 보실 수 있습니다.

 

간단하게 보자면

int8_t = signed char

int16_t = short int

int32_t = int

int64_t = __WORDSIZE 가 64라면 long int 아니라면 long long int 입니다. 

(* __WORDSIZE에는 compile 타임에 32 bit를 사용하는지 64 bit 사용하는지를 저장합니다.)

 

int*_t 의 경우 int, uint*_t 의 경우 unsigned int로 정의 합니다.

 

잘 정리된 표가 있는데요, 해당 자료형을 사용하면 위와 같이 각 변수별로 할당하는 bit의 수가 int*_t 의 *에 맞게 고정이 됩니다.

 

출처: https://www.programmersought.com/article/66902704891/ 

위의 표가 맞는 지 간단한 코드로 확인해보도록 하겠습니다.

#include <stdio.h>
#include <stdint.h>

void main(){
        uint8_t unsigned_char = 0;
        uint16_t unsigned_short = 0;
        uint32_t unsigned_int = 0;
        uint64_t unsigned_long_long = 0;
        printf("Size of uint8_t : %ld max: %u\n",sizeof(unsigned_char), (unsigned char)((~unsigned_char) >> 1));
        printf("Size of uint16_t: %ld max: %u\n",sizeof(unsigned_short), (unsigned short)((~unsigned_short) >> 1));
        printf("Size of uint32_t: %ld max: %u\n",sizeof(unsigned_int), (~unsigned_int) >> 1); 
        printf("Size of uint64_t: %ld max: %lu\n",sizeof(unsigned_long_long), (~unsigned_long_long) >> 1); 
}

현재 사용 중인 머신은 64bit Linux 입니다.
코드 실행 결과

위의 코드를 실행하면 각 변수별로 할당된 byte 수와 max값이 위의 표와 일치하는 것을 알 수 있습니다.

* max 값의 출력을 위해 uint8_t과 uint16_t는 type casting을 했습니다. 

2. 그렇다면 이 자료형은 왜 쓰는 건가요?

stdint의 자료형은 각 자료형이 사용하는 bit 수를 고정합니다. 모든 플랫폼에서 동일한 bit 수를 사용하게 되는거죠. 그렇기 때문에 어떤 플랫폼에서 프로그램을 실행하든지 동일한 bit 수를 사용한 자료형을 사용할 수 있습니다. 즉, 이식성(Portability)를 위해서 입니다.

 

예를 들어, 임베디드처럼 메모리 사용의 관리를 비교적 많이 신경써줘야하는 곳이라면 해당 데이터 타입을 사용해서 컨트롤하는 경우가 많습니다.