Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++에서 정수 오버플로 감지하고 확인하는 방법


정수 오버플로를 다루는 가장 안전한 방법은 오버플로가 발생하기 전에 미리 검사하는 것입니다. 하지만 이미 발생한 오버플로를 확인하는 몇 가지 트릭성 방법들도 존재합니다.

부호 없는 정수 덧셈의 오버플로 감지

예를 들어 unsigned int 덧셈에서 오버플로를 감지하려면, 연산 결과가 실제로 더해진 두 값 중 하나보다 작아졌는지 확인하면 됩니다.

예제 코드

unsigned int x, y;
unsigned int value = x + y;
bool overflow = value < x; // "value < y"로 검사해도 동일하게 동작합니다

이 방법이 작동하는 이유는 다음과 같습니다. xy가 모두 부호 없는 정수일 때, 두 값을 더하는 과정에서 오버플로가 발생하면 결과 값은 절대 원래 값보다 클 수 없습니다. 오버플로로 인해 값이 랩어라운드(wrap-around)된 후 원래 값보다 앞서 나가려면 unsigned int가 표현할 수 있는 최대값보다 커야 하는데, 그런 값은 저장 자체가 불가능하기 때문입니다. 따라서 결과가 피연산자보다 작다면 오버플로가 발생했다고 확신할 수 있습니다.

CPU 오버플로 플래그 활용

또 다른 방법은 CPU의 오버플로 플래그(Overflow Flag)에 직접 접근하는 것입니다. 일부 컴파일러는 이 플래그를 읽거나 테스트할 수 있는 기능을 제공하지만, 이는 C++ 표준이 아니므로 특정 플랫폼이나 컴파일러에 종속적이라는 단점이 있습니다. 즉, 코드의 이식성(portability)이 크게 떨어질 수 있습니다.

컴파일러 내장 함수 사용

실무에서는 GCC나 Clang이 제공하는 __builtin_add_overflow, __builtin_sub_overflow, __builtin_mul_overflow 같은 내장 함수(built-in function)를 사용하는 것이 좋습니다. 이 함수들은 연산 전에 안전하게 오버플로 여부를 판별해 주며, MSVC에서도 유사한 기능(_addcarry_u32 등)을 제공합니다. 또한 C++26부터는 표준 라이브러리 차원에서 오버플로를 처리하는 기능이 도입될 예정이므로, 최신 표준을 사용할 수 있다면 해당 기능을 활용하는 것이 바람직합니다.

정리

  • 가장 안전한 방법: 연산 전에 오버플로 가능성을 미리 검사합니다.
  • 간단한 트릭: 부호 없는 정수 덧셈의 경우 결과 값이 피연산자보다 작은지 비교합니다.
  • 비표준 방법: CPU 오버플로 플래그 접근은 가능하지만 이식성이 없습니다.
  • 권장 방법: 컴파일러 내장 함수를 사용하면 안전하고 효율적으로 오버플로를 감지할 수 있습니다.