2017-02-07 1 views
1

inner_LOAD_ATOM(buffer, ATOM_MAX)scanf("%" "ATOM_MAX" "s", x)으로 변환되었지만 줄 바꿈 된 버전이 아닌 이유는 무엇입니까? ATOM_MAX (식별자)가 inner_LOAD_ATOM 또는 LOAD_LINE에 "전달"되기 전에 10으로 바뀌고 래퍼가 쓸모 없게됩니다. 래퍼가 왜 필요한지에 대한 정교한 대답은 매우 높이 평가 될 것입니다. 첫 번째 패스 #y#ATOM_MAX로 대체하고도 캐릭터 라인 얻을 것이다 때문에매크로는 대체 매크로 대신 이전 매크로 식별자를 문자열 화합니다.

#include <stdio.h> 

#define ATOM_MAX 10 
#define inner_LOAD_ATOM(x, y) scanf("%" #y "s", x)  /* inner part */ 
#define LOAD_ATOM(x, y) inner_LOAD_ATOM(x, y)   /* wrapper of inner_LOAD_ATOM */ 


int main(void) 
{ 
    char buffer[ATOM_MAX] = {0, }; 

    /* wrapped works fine */ 
    LOAD_ATOM(buffer, ATOM_MAX);   

    /* [Warning] unknown conversion 
    type character 'A' in format [-Wformat=] */ 
    inner_LOAD_ATOM(buffer, ATOM_MAX); 

    printf("%s\n", buffer); 


    return 0; 
} 

답변

2

그것은 C 함수처럼 작동하지 않는 기능과 같은 매크로를 이해하는 것이 중요합니다. 하나의 매크로에서 다른 매크로로 인수를 전달하거나 매크로 호출 스택에 대한 인식이 거의 없다. 대신 매크로 확장이 반복적으로 진행됩니다. 즉, 매크로가 확장으로 바뀌면 확장이 더 이상 매크로가 확장되도록 다시 스캔됩니다.

함수와 같은 매크로의 인자들은 문자열 화 (stringification) (#) 또는 토큰 - 붙이기 (##) 연산자의 피연산자 제외한 매크로의 대체 텍스트, 삽입되기 전에 완전히 매크로 확장된다. 따라서 inner_LOAD_ATOM(buffer, ATOM_MAX)을 직접 호출하면 # 연산자를 적용하기 전에 ATOM_MAX이 확장되지 않습니다.

반면에 LOAD_ATOM(buffer, ATOM_MAX)을 호출하면 LOAD_ATOM()이 확장되기 전에 ATOM_MAX 매크로가 확장됩니다. inner_LOAD_ATOM()은 그 시점을 고려하지 않습니다. 추가 매크로 확장을 위해 LOAD_ATOM()의 확장을 다시 스캔 할 때까지 외부 매크로의 대체 텍스트의 일부일뿐입니다.

1

. 따라서 두 번째 패스에서는 확장되지 않습니다. 그냥 수동으로 실행하자

첫 번째 패스 :

int main(void) 
{ 
    char buffer[10] = {0, }; 

    /* wrapped works fine */ 
    inner_LOAD_ATOM(buffer, 10); // <-- Note - here it ATOM_MAX was expanded in the first pass  

    /* [Warning] unknown conversion 
    type character 'A' in format [-Wformat=] */ 
    scanf("%" "ATOM_MAX" "s", buffer); 

    printf("%s\n", buffer); 


    return 0; 
} 

두 번째 패스 :

int main(void) 
{ 
    char buffer[10] = {0, }; 

    /* wrapped works fine */ 
    scanf("%" "10" "s", buffer);   

    /* [Warning] unknown conversion 
    type character 'A' in format [-Wformat=] */ 
    scanf("%" "ATOM_MAX" "s", buffer); // <----- Not expanded as is interpreted as string 

    printf("%s\n", buffer); 


    return 0; 
}