C++ 프로그래밍에서 부동소수점(float) 값을 정수(integer)로 변환하는 과정에서 예상치 못한 심각한 문제가 발생할 수 있다는 사실이 다시금 주목받고 있습니다. 소수점을 버린 부동소수점 값이 대상 정수형의 표현 범위를 초과할 경우, C++ 표준은 이를 '정의되지 않은 동작(Undefined Behavior, UB)'으로 규정합니다. 이는 단순히 잘못된 결과값을 얻는 것을 넘어, 프로그램이 예측 불가능하게 오작동하거나 심지어 보안 취약점으로 이어질 수 있는 위험을 내포합니다.
이러한 UB는 암시적 변환, 함수형 캐스트(예: int(f)), 그리고 static_cast 등 모든 형태의 변환에서 발생할 수 있습니다. 더 큰 문제는 대부분의 컴파일러 경고 옵션(예: -Wall, -Wextra)이 이를 탐지하지 못한다는 점입니다. 심지어 암시적 변환만 경고하는 -Wconversion 옵션도 모든 경우를 잡아내지 못합니다. 마이크로소프트(Microsoft)의 안전한 축소 변환 함수인 gsl::narrow조차 일부 부동소수점 입력에서 UB를 일으켜, 문서에 명시된 '표현 불가능한 값에 예외를 던진다'는 동작을 지키지 못하는 사례도 발견되었습니다. 또한, x86과 AArch64 아키텍처 간에 이러한 변환 시 처리 방식이 달라 하드웨어에 따라 결과가 상이할 수 있어 이식성 문제까지 야기합니다.
이러한 위험을 피하기 위한 가장 확실한 방법은 부동소수점 값을 정수로 캐스트하기 전에 대상 정수형의 범위를 벗어나지 않는지 직접 검사하는 것입니다. 또한, Clang과 GCC 컴파일러의 Undefined Behavior Sanitizer(UBSan) 옵션인 -fsanitize=float-cast-overflow를 사용하면 이러한 UB를 실행 시점에 탐지할 수 있습니다. Rust와 같은 다른 현대 언어들은 이러한 변환 규칙을 명확히 정의하여 UB를 방지하고 있으며, C++ 역시 C++26 표준에서 불합리한 UB를 제거하려는 움직임을 보이고 있어 향후 개선이 기대됩니다. 개발자들은 이러한 언어의 미묘한 동작 방식을 정확히 이해하고 안전한 코딩 습관을 들여야 합니다.