핵심 요약
- C++26 표준(P2809R3)을 통해 본문이 비어 있는 단순 무한 루프(while (true);)가 더 이상 정의되지 않은 동작(UB)이 아닌 정상 동작으로 규정되었습니다.
- 이전 C++에서는 부수 효과 없는 무한 루프를 컴파일러가 임의로 삭제해 뒤쪽 엉뚱한 코드가 실행되는 황당한 최적화 사고와 임베디드 시스템 취약점이 발생하곤 했습니다.
- 이번 변경은 결함 보고서(DR)로도 승인되어 이전 C++ 버전 컴파일러 모드에도 소급 적용될 수 있습니다.
요약 C++ 개발자들 사이에서 오랫동안 황당한 버그와 최적화 사고의 원인으로 지목되던 'while(true);' 무한 루프 문제가 C++26 표준에 이르러 마침내 해결되었습니다. 기존 C++11 이후 표준에서는 부수 효과(I/O, 동기화, 원자적 연산 등)가 없는 무한 루프를 정의되지 않은 동작(UB, Undefined Behaviour)으로 취급해 왔습니다. 이 때문에 컴파일러는 루프가 결국 종료된다고 가정하고 코드를 완전히 날려버리는 극단적인 최적화를 수행하곤 했습니다.
실제로 Clang 등 주요 컴파일러에서 'while(true);'를 빈 루프로 두고 바로 뒤에 도달할 수 없는 함수를 배치하면, 컴파일러가 무한 루프를 통째로 지우고 뒤쪽 코드를 곧바로 실행해버려 'Hello world!'가 출력되는 황당한 현상이 발생했습니다. 이는 단순한 해프닝에 그치지 않고 임베디드나 커널 개발 환경에서 치명적인 보안 취약점을 낳았습니다. OS가 없는 베어메탈 환경에서는 하드웨어 초기화 실패 같은 치명적 오류 발생 시 기기를 정지시키기 위해 'while(true);'로 시스템을 멈춰 세우는 패턴을 흔히 사용하는데, 컴파일러가 이를 지워버려 기기가 망가진 상태로 다음 메모리의 코드를 제멋대로 실행하는 사고가 벌어졌기 때문입니다.
재미있는 점은 똑같이 2011년에 표준을 정비한 C 언어(C11)의 경우 조건식이 상수 표현식인 루프는 종료를 가정하지 못하도록 예외 규정을 두어 'while(1);'이 정상 작동했던 반면, C++은 이를 도입하지 않아 두 언어 간 불필요한 차이가 존재했다는 사실입니다.
이번 C++26에서 채택된 P2809R3 제안은 본문이 완전히 비어 있고 조건식이 참인 상수 표현식인 경우를 '자명한 무한 루프(trivial infinite loop)'로 규정하여 공식적으로 허용했습니다. 표준 라이브러리 환경에서는 해당 루프 본문이 'std::this_thread::yield()' 호출로 대체되어 진행 보장을 충족하게 됩니다. 또한 이 제안은 결함 보고서(Defect Report)로 승인되었기 때문에, 최신 컴파일러에서는 C++20 등 이전 표준 모드에서도 이미 해당 수정 사항이 소급 적용되어 더 이상 무한 루프가 증발하지 않도록 개선되고 있습니다.
Sponsored · 광고