아래 코드를 보자.

typedef unsigned int UINT32;

std::string text = GetText();
for(UINT32 i = text.size() - 1; i >= 0; --i)
{
    // 텍스트를 뒤에서부터 읽어서 처리
    DoSomething(text[i]);
}
주석처럼 스트링을 뒤에서부터 읽어가면서 뭔가 처리를 하려고 한다. 그런데 프로그램이 뻗어버린다.

이유는 unsigned 때문이다. i가 0까지는 잘 내려오지만, 그 직후에 언더플로우가 발생해버린다. 그러면 약 42억의 수를 가지게 될 테고... 결과는? 쾅~


int를 사용하면 되겠지만, 저기 std::string::size() 라는 녀석은 리턴값이 size_t이다. 즉 unsigned int와 같다. unsigned와 int를 섞게 되면 컴파일러가 경고를 하게 된다. 경고는 당연히 피해야 하는 것이고 따라서 위와 같이 unsigned를 사용했던 것이다.



위 코드에서는 STL 자료구조가 사용된 관계로, 그냥 reverse_iterator를 사용하면 해결된다. 하지만 index를 알아야 하는 경우가 있다면... 어떻게 해야 할까?

내 생각엔 int i = static_cast<int>(text.size() - 1) 처럼 사용하는게 낫지 않나 싶다. 가독성이 좀 떨어지는 단점이 있지만 딱히 방법이 없다.

이럴 땐 Java처럼 unsigned를 안쓰는 정책을 사용하거나, C#처럼 웬만하면 기본 라이브러리는 int형을 최대한 사용하고 signed와 unsigned가 같이 쓰이는 경우 컴파일 에러(심지어 케스팅을 해도)를 발생시켜주는 언어가 약간 부럽다.


반응형

+ Recent posts