2016-09-14 5 views
2

sizeof이 컴파일 타임 연산자인지 평가합니다. See here.sizeof 연산자는 gcc의 컴파일 단계에서

편집 작업에는 많은 단계가 있습니다. 어떤 단계에서 sizeof 연산자가 평가됩니까? 전처리 변환 장치를 생산하는 전처리 실행 후

+0

어떻게 모든 "컴파일"상태는? –

+3

전처리 기가 실행 된 후 (전처리 기는'sizeof'를 인식하지 못합니다.) 객체 파일이 어셈블러에서 생성되거나 링크되어 실행 파일을 생성하기 전에 평가됩니다. 따라서 주 컴파일러에서 평가됩니다. 전처리 기와 컴파일러 및 어셈블러 (실제로 링커)는 모두 단일 프로그램이거나 여러 프로그램이 될 수 있습니다. 표준은 상관하지 않는다. 예외는 VLA 가변 길이 배열의 크기입니다. 그것은 컴파일 타임 대신 런타임에 평가 될 필요가 있습니다. –

+0

@JonathanLeffler 답변으로 게시해야합니다. – Lundin

답변

3

일반적으로, 컴파일러 (전체 헤더 파일 #include의 위치에 붙여 넣기, #define 's은 (는) 모든 장소, 완전히 제거 #ifdef 조건문 등의 비활성 지점을 통해 대체) 실행됩니다. 대부분의 최신 컴파일러는 일반적으로 전처리 자체를 수행 할 수도 있지만 역사적인 이유로 C 전처리 기 (cpp)와 C 컴파일러 (cc)는 적어도 개념적으로 구별됩니다. 전자의 출력은 후자의 입력으로 사용됩니다.

결과적으로이 단계가 무엇인지, 순서가 무엇인지는 컴파일러의 내부 구현에 달려 있습니다. 그러나 가장 전통적인 "파이프 라인"은 다음과 같습니다.

  • Lexing : 서로 토큰을 분리합니다.
  • 구문 분석 : 언어 문법에 따라 토큰의 조합을 해석하고 구문 분석 트리를 생성합니다.
  • 추상 구문 트리 생성 : 구문 분석 트리가 입력으로 사용되며보다 사용하기 쉽고 주석이 잘된 트리가 생성됩니다.
  • 범위 분석 : 사용 된 식별자를 각각의 선언과 일치시키고, 선언되지 않은 식별자의 경우 오류를 방출합니다.
  • 형식 검사 : 각 식의 형식이 특정 상황에서 예상되는 형식과 일치하는지 확인합니다. 이 단계가 끝나고 오류가 발생하지 않으면 프로그램은 구문 상 및 의미 상 올바르다 고 간주되므로 다음 단계를 진행할 수 있습니다.
  • 코드 생성 및 최적화 : 아마도이 단계에서 컴파일러는 sizeof(int)을 나타내는 추상 노드 대신에 4을 방출합니다. 또한 3 + 4과 같은 상수 표현을 7에 씹었습니다. sizeof이 경우 런타임에서 평가 될 수

참고는 (C99 이후)는 가변 길이 배열에 적용된다 :

int n; 
n = ...; 
int vl_arr[n]; 
sizeof(vl_arr); // could be evaluated at runtime if "n" is not known at compile-time