C++26: 단순 무한 루프는 더 이상 미정의 동작이 아님

46 minutes ago 2

C++26은 while (true);처럼 조건이 항상 참이고 본문이 비어 있는 단순 무한 루프(trivial infinite loop) 의 동작을 정의하며, 컴파일러가 미정의 동작을 근거로 이를 제거할 수 없게 함 기존 전방 진행 보장(forward progress guarantee) 아래에서는 이런 루프에 영원히 머무는 실행이 미정의 동작이었으며, 실제로 Clang이 루프를 제거해 뒤에 배치된 함수가 실행되는 사례가 있음 보호 대상은 문법적으로 비어 있는 본문과 참으로 평가되는 상수 표현식 조건을 갖춘 루프로 한정되며, 의미 없는 문장이라도 본문에 있으면 제외됨 치명적 오류 발생 시 무한 루프로 실행을 멈추는 임베디드/커널 코드에서도 이 변경이 중요하며, 프리스탠딩 구현에서 std::this_thread::yield()로 본문을 대체할지는 구현 정의임 변경안 P2809R3는 결함 보고서로도 채택돼 이전 C++ 모드에 소급 적용될 수 있으며, 최신 컴파일러에서는 C++20 모드에서도 과거 동작이 재현되지 않을 수 있음 기존 무한 루프가 미정의 동작이었던 이유 C++11에서 스레드 지원과 함께 도입된 전방 진행 보장에 따르면, 구현은 모든 스레드가 결국 다음 중 하나를 수행한다고 가정할 수 있었음 종료함 라이브러리 I/O 함수를 호출함 volatile glvalue에 접근함 동기화 연산 또는 원자적 연산을 수행함 while (true);는 어느 항목도 수행하지 않으므로, 기존 규칙에서는 이 루프에 영원히 머무는 실행이 미정의 동작이었음 최적화기는 실행이 루프에 갇히지 않는다고 가정해 루프를 제거하거나 해당 경로를 도달 불가능한 것으로 처리할 수 있었음 Clang 재현 예제에서는 main 안의 무한 루프가 제거된 뒤 실행이 이어져, 링커가 뒤에 배치한 unreachable() 함수가 “Hello world!”를 출력함 이는 컴파일러 버그가 아니라 미정의 동작으로 허용되던 결과임 C와의 차이, 임베디드 코드의 실제 문제 C11도 전방 진행 규칙을 도입했지만, 제어 표현식이 상수 표현식인 루프는 종료한다고 가정할 수 없다는 예외를 포함함 따라서 while (1);은 C11 이후 C에서는 동작이 정의돼 있었지만, 해당 규칙을 채택하지 않은 C++에서는 미정의 동작이었음 임베디드/커널 코드에서는 치명적 오류가 발생하고 종료할 운영체제도 없을 때 오류 시 정지 패턴으로 빈 무한 루프를 사용함 예를 들어 하드웨어 초기화 실패...

Read Entire Article