as-if 규칙

as-if 규칙 (The as-if rule)

컴파일러가 코드를 마음대로 바꿔도 되는 건 어디까지일까 궁금해하는 분이 많아요. 핵심은 간단해요. "눈에 보이는 동작(observable behavior)만 바꾸지 않는다면 어떤 코드 변환이든 다 허용한다"는 게 바로 as-if 규칙이에요. 지금 실행하는 C 코드가 어떻게 최적화되는지 알려면 이 규칙을 이해해야 해요.

출처: cppreference

본문

프로그램의 관찰 가능한 동작을 바꾸지 않는 코드 변환은 어느 것이든 허용돼요.

설명

C 컴파일러는 다음과 같은 조건이 계속 성립하기만 하면 프로그램을 어떤 방식으로든 변경할 수 있어요.

  1. 모든 시퀀스 포인트에서 모든 volatile 객체의 값이 안정적이다 (이전 평가가 완료됐고, 새 평가가 시작되지 않았다). (until C11)

  2. volatile 객체에 대한 접근(읽기와 쓰기)이 그것이 등장하는 표현식의 의미론에 엄격히 따라서 발생한다. 특히 같은 스레드의 다른 volatile 접근에 대해 재배치되지 않는다. (since C11)

  3. 프로그램 종료 시, 파일에 쓰여진 데이터가 프로그램이 그대로 실행된 것과 정확히 같다.

  4. 대화형 장치로 보내지는 프롬프트 텍스트는 프로그램이 입력을 기다리기 전에 표시된다.

  5. #pragma STDC FENV_ACCESS가 지원되고 ON으로 설정되어 있으면, 부동소수점 환경(부동소수점 예외와 반올림 모드)에 대한 변경이 작성된 그대로 실행된 것처럼 부동소수점 산술 연산자와 함수 호출에서 관찰된다. 단, 다음은 예외다:

  • cast와 대입 외의 부동소수점 표현식의 결과는 표현식의 타입과 다른 부동소수점 타입의 범위와 정밀도를 가질 수 있다 (FLT_EVAL_METHOD 참고),
  • 위에도 불구하고, 어떤 부동소수점 표현식의 중간 결과는 무한한 범위와 정밀도로 계산될 수 있다 (#pragma STDC FP_CONTRACT가 OFF가 아니라면). (since C99)

주의

이 섹션은 cppreference의 C++ as-if 규칙 문서처럼 상세하게 채워지지 않았어요. as-if 규칙의 더 풍부한 예시와 논의는 그 문서를 참고하면 좋아요.

더 알아보기

  • 컴파일러가 코드를 재배치·변환하는 기준이 되는 시퀀스 포인트와 평가 순서는 관련 문서에서 볼 수 있어요.
  • 번역 단계와 전처리 과정은 번역 단계 문서에서 다뤄요.
  • cppreference의 as-if 규칙 원문과 C++ 버전 as-if 규칙을 참고할 수 있어요.