본문 바로가기

Library/C/C++

std::size_t를 언제 사용해야 하는가?

STL 벡터와 같은 컨테이너를 사용할 때 사소하지만 잠깐 고민되는 부분은, size()와 같은 메서드를 호출할 때 값을 저장할 변수를 어떤 것으로 선언하느냐이다. 물론, 대부분은 정수형을 사용하겠지만 정확하게 어떤 형일까?

벡터와 같은 경우, std::vector::size_type이 정확한 리턴 타입이며, size_type은 allocator< T >의 size_type과 같다. 또, size_type은 cstddef에 선언된 size_t와 동일한 타입이다. size_t는 sizeof 연산자의 리턴 타입이며, unsigned int이고, 기계에 의존적인 값이다. 부호가 있든 없든 일단 정수형이므로, 정수형을 사용한다고 하는 것은 틀린 말은 아니지만 좀 더 명확하게 논리적인 제한을 가할 필요가 있다. 즉, std::size_t는 이식성과 명확한 의미를 강조하기 위한 것이다.

사실, int로 선언하든지 unsigned int로 선언하든지 타입 변환이 가능하다면 컴파일러에 의해 암묵적인 변환이 이루어지지만, 경고 여부는 컴파일러에 따라 다르다. 실제로 부호 없는 정수형과 부호 있는 정수형을 혼용해서 사용하다가 어처구니 없는 버그를 만들어낼 수도 있으며, 가급적이면 정확하게 타입을 맞추어서 사용하는 것이 바람직하다. 즉, 조건문에서 변하지 않는 값을 왼쪽에 배치하여 == 연산자와 = 연산자를 잘못 코딩한 경우 컴파일러에 의해 잡아내는 것과 비슷한 접근법이라 할 수 있다(동일한 문제라는 뜻은 아니다).

예를 들어, 배열 안의 인덱스로 사용할 타입은 int 타입도 상관없지만 크기가 0보다 적은 배열이란 무의미하므로 std::size_t 타입으로 선언해주는 것이 더 좋다. 또, std::vector::size() 메서드와 같은 경우도 음수가 되는 용량이란 존재할 수 없으므로, 이것 역시 std::size_t 타입의 변수로 그 값을 받는 것이 적절할 것이다.

물론, 이것은 컴파일러 입장에서 보면 프로그래머에 의한 논리적인 버그 문제 외에 큰 의미가 없다. 그러나, std::size_t 타입은 조금 더 분명하게 의미를 전달하는 부수적인 효과가 있기 때문에, 코드의 가독성과 논리성을 좀 더 높여줄 수 있을 것이다.