as-if 규칙
as-if 규칙 (The as-if rule)
컴파일러가 코드를 마음대로 바꿔도 되는 건 어디까지일까 궁금해하는 분이 많아요. 핵심은 간단해요. "눈에 보이는 동작(observable behavior)만 바꾸지 않는다면 어떤 코드 변환이든 다 허용한다"는 게 바로 as-if 규칙이에요. 지금 실행하는 C 코드가 어떻게 최적화되는지 알려면 이 규칙을 이해해야 해요.
출처: cppreference
본문
프로그램의 관찰 가능한 동작을 바꾸지 않는 코드 변환은 어느 것이든 허용돼요.
설명
C 컴파일러는 다음과 같은 조건이 계속 성립하기만 하면 프로그램을 어떤 방식으로든 변경할 수 있어요.
-
모든 시퀀스 포인트에서 모든 volatile 객체의 값이 안정적이다 (이전 평가가 완료됐고, 새 평가가 시작되지 않았다). (until C11)
-
volatile 객체에 대한 접근(읽기와 쓰기)이 그것이 등장하는 표현식의 의미론에 엄격히 따라서 발생한다. 특히 같은 스레드의 다른 volatile 접근에 대해 재배치되지 않는다. (since C11)
-
프로그램 종료 시, 파일에 쓰여진 데이터가 프로그램이 그대로 실행된 것과 정확히 같다.
-
대화형 장치로 보내지는 프롬프트 텍스트는 프로그램이 입력을 기다리기 전에 표시된다.
-
#pragma STDC FENV_ACCESS가 지원되고 ON으로 설정되어 있으면, 부동소수점 환경(부동소수점 예외와 반올림 모드)에 대한 변경이 작성된 그대로 실행된 것처럼 부동소수점 산술 연산자와 함수 호출에서 관찰된다. 단, 다음은 예외다:
- cast와 대입 외의 부동소수점 표현식의 결과는 표현식의 타입과 다른 부동소수점 타입의 범위와 정밀도를 가질 수 있다 (FLT_EVAL_METHOD 참고),
- 위에도 불구하고, 어떤 부동소수점 표현식의 중간 결과는 무한한 범위와 정밀도로 계산될 수 있다 (
#pragma STDC FP_CONTRACT가 OFF가 아니라면). (since C99)
주의
이 섹션은 cppreference의 C++ as-if 규칙 문서처럼 상세하게 채워지지 않았어요. as-if 규칙의 더 풍부한 예시와 논의는 그 문서를 참고하면 좋아요.