2017-01-03 9 views
1

전처리 기가 매크로를 처리하여 컴파일러로 가져 오기 전에 구문 오류를 생성하지 않는 한 #define#include은 어디에서나 작성할 수 있다는 인상을 받았습니다.C 코드에서`# define '의 위치가 중요합니까?

나는 다음과 같은 코드를 실행 :

#include <stdio.h> 

int main(void) { 
    int B = A; 
    #define A 4 
    printf("%d", B); 
    return 0; 
} 

을하며 다음과 같은 오류 발생 :

prog.c: In function 'main': prog.c:4:13: error: 'A' undeclared (first use in this function) int B = A; ^prog.c:4:13: note: each undeclared identifier is reported only once for each function it appears in

을하지만이 작업을 수행 할 때, 그것을 작동합니다!

#include <stdio.h> 

int main(void) { 
    #define A 4 
    int B = A; 
    printf("%d", B); 
    return 0; 
} 

확실하지 내가 여기없는,하지만 컴파일러는 오류 "선언되지 않은 A"를 줄 않는 이유는 무엇입니까?

는 있도록되어 전처리가 #define A 4 라인을 판독 할 때 코드의 후속 행에서 모든 A 4로 대체를 시작합니까?

+1

아니요. 전처리 지시문을 어디에 두는가가 중요합니다. 또한 컴파일 타임에 오류가없는 것은 유효한 프로그램에 대한 필수 조건이지만 확실히 충분하지는 않습니다. –

답변

10

파일은 전처리 단계와 컴파일 단계에서 위에서 아래로 파싱됩니다. (참고 : MSalters는 각 단계가 맨 위에서 별도로 시작됨을 나타냅니다.

토큰 define d가 나타날 때까지 전처리 기가 A을 대체하지 않습니다.

Is it so that when pre-processor reads the line #define A 4 it will start replacing any A with 4 from the subsequent lines of code?

예. 너는별로 놓치지 않았다.

+1

아마 그것을 명백하게하기 위해서 : 전처리 단계는 위에서 아래로 진행하고 컴파일 단계는 맨 위에서 시작합니다. – MSalters

+0

@MSalters - 개선 된 제안에 감사드립니다. – StoryTeller

1

전처리 지시문의 위치는 전처리 기가 C 구문에 대해 알지 못하기 때문에 중요하지 않습니다.

전처리 기 (즉, 파일 분석의 4 단계)는 다른 언어를 사전 처리 할 수도 있습니다.

사전 처리 라인은 공백으로 시작하여 그 다음에 #이옵니다. 그렇게 시작하지 않는 모든 행은 텍스트 코드 행으로 간주됩니다.

당신이 예를

f(
#if cond1 
a 
#elif cond2 
b 
#else 
c 
#endif 
) 

를 들어, 어떤 조건에 따라 서로 다른 매개 변수를 선택하거나 해당

int[] a = { 
      #include data-file 
      } 
같은 배열을 초기화 할 #INCLUDE를 사용할 수있는 경우 함수 내에서 #DEFINE을 포함하는 것이 일반적이다

또는 #define을 사용하여 일부 조건에 따라 구문을 변경할 수 있습니다.

f() 
{ 
#if arch 
#define static 
#endif 
static int x; 
... 
#undef static 
} 

가 #DEFINE의 값 nil를 갖는 처리기의 환경에서 대상 매크로 static 삽입되며,이 오브젝트가 라인 #define static 간의 유효 : 아치에 해당하는 경우, 예를 들어, 정적 키워드 static 고려되지 및 #undef.

귀하의 경우에는 변수 A를 사용하기 전에 한 줄 전에 정의하십시오.

-2

'A'는 'A'의 수명이 해당 중괄호 (주 루프에만 해당)에 대해 제한되도록 정의되었습니다. 중괄호에서는 순차적으로 코드가 실행되고 정의하기 전에 'A'를 사용하고 있습니다.

+0

첫 번째 진술이 잘못되었습니다. 전처리는 C 범위에 대해 알지 못합니다. http://ideone.com/EMXxyN – bolov

0

아니요. 그렇게하고 싶을 때 어디에서나 정의하고 정의를 취소 할 수 있습니다. 그러나 매크로를 사용하기 전에 매크로를 정의해야합니다. 매크로를 선언하기 전에 매크로를 사용했습니다.

전처리 기는 "크리스탈 볼"이 없으며 미리보기 않습니다. 매크로를 정의한 경우 해당 매크로는 파일 끝이나 #undef 토큰이 발견 될 때까지 유효합니다.