Signed Integer Overflow

by Vincent Lee,

C/C++ 표준에서 signed int 타입의 연산이 오버플로우(overflow)하면 그 결과는 정의되지 않는다(undefined behavior). 즉, INT_MAX+1은 INT_MIN이 될 것을 보장하지 않는다. C#의 경우 OverflowException 예외가 발생하며, 한편 Java에서는 오버플로우(wrap)되는 것을 보장한다. 컴파일러가 언어 표준상의 이런 “미정의 동작”을 어떻게 다루는지1 알고 있지 않으면 디버그 빌드와 릴리스 빌드에서 같은 소스 코드의 프로그램이 다르게 동작하여 당황하게 되기도 한다.2

C/C++ 컴파일러는 자기 관점에서 미정의 동작을 처리할 필요가 없으므로 signed int 타입의 오버플로우는 일어나지 않을 것으로 간주하여 이것을 최적화에 활용한다. 예를 들어, x+1 > x를 항상 참(true)인 식으로 평가한다. 만약 x가 오버플로우된다면 이렇게 할 수 없다.

덧셈, 뺄셈, 나눗셈 등의 다양한 연산에 대하여 오버플로우를 사전에 검사하는 방법은 CERT C Secure Coding Standard3에 잘 설명되어 있다. 또한, C/C++에서 정수의 오버플로우에 관한 자세한 설명과 Clang을 활용한 컴파일 타임과 런타임에 각각 오버플로우를 감지하는 방법의 설계와 구현에 대하여 Understanding Integer Overflow in C/C++4에서 잘 설명하고 있다.

References

1 What Every C Programmer Should Know About Undefined Behavior (Chris Lattner)

2 Why does this code fail in release? (Gregg Tavares)

3 Ensure that operations on signed integers do not result in overflow (CERT C Secure Coding Standard)

4 Understanding Integer Overflow in C/C++ (Will Dietz, Peng Li, John Regehr and Vikram Adve)