C++에서 변수가 해당 데이터 타입이 표현할 수 있는 유효 범위를 초과하면 개발자가 의도하지 않은 결과가 발생합니다. 가장 흔한 문제는 값이 최솟값으로 되감기면서(wrap-around) 반복문이 종료 조건을 만족하지 못해 무한 루프에 빠지는 것입니다. 이 글에서는 char, bool, unsigned short 타입을 예시로 범위 초과 시 어떤 일이 일어나는지 살펴보겠습니다.
1. char 타입의 범위 초과
char 타입은 1바이트 크기로 일반적으로 -128부터 127까지의 값을 저장할 수 있습니다. 아래 코드는 0부터 300까지 문자를 출력하려는 의도로 작성되었지만, 실제로는 무한 루프에 빠집니다.
#include <iostream>
using namespace std;
int main() {
for (char x = 0; x <= 300; x++)
cout << x;
return 0;
}
출력 결과: 문자가 무한히 출력됩니다.
x가 127에 도달한 후 1이 증가하면 128이 아니라 다시 -128로 되돌아갑니다. 따라서 조건식 x <= 300은 항상 참이 되어 루프는 절대 종료되지 않습니다.
2. bool 타입의 범위 초과
bool 타입은 0(false)과 1(true) 두 값만 저장할 수 있습니다. 아래 예제에서는 x를 1부터 시작해 6까지 증가시키려 하지만, 1에서 1을 더해 2가 되려는 순간 다시 1로 되돌아가므로 1이 무한히 출력됩니다.
#include <iostream>
using namespace std;
int main() {
bool x = true;
for (x = 1; x <= 6; x++)
cout << x;
return 0;
}
출력 결과:
1111………
3. unsigned short 타입의 범위 초과
부호 없는(unsigned) 정수 타입인 unsigned short는 0부터 65535까지 저장할 수 있습니다. 이 경우 값이 범위를 벗어나면 마치 모듈러 연산처럼 동작하여 65535 다음에는 다시 0으로 돌아갑니다.
#include <iostream>
using namespace std;
int main() {
unsigned short x;
for (x = 65530; x <= 65536; x++)
cout << x << ", ";
return 0;
}
출력 결과:
65530, 65531, 65532, 65533, 65534, 65535, 0, 1, …………
65535까지 출력된 후 x는 0이 되고, 0은 여전히 65536보다 작으므로 조건식이 계속 참을 유지하게 됩니다. 결국 이 경우에도 숫자가 무한히 출력됩니다.
정리 및 주의 사항
이처럼 데이터 타입의 범위를 초과하면 값이 되감겨 반복문의 종료 조건이 영원히 만족되지 않을 수 있습니다. 특히 부호 있는(signed) 정수 타입에서 범위를 초과하는 것은 C++ 표준상 미정의 동작(undefined behavior)으로 분류되므로, 컴파일러에 따라 전혀 다른 결과가 나타날 수 있다는 점도 유의해야 합니다.
이러한 문제를 예방하려면 다음과 같은 방법을 권장합니다.
- 저장할 값의 크기를 고려해 int, long long 등 충분히 큰 타입을 사용합니다.
- 반복문 카운터는 저장하려는 값보다 넉넉한 타입으로 선언합니다.
- 컴파일러 경고 옵션(-Wall 등)을 활성화하여 잠재적 오버플로를 미리 확인합니다.