2013-09-25 3 views
11

수신하는 인수에 따라 다른 것으로 확장되는 C 전 처리기 매크로를 작성하는 방법이 있습니까?C 매크로 안에 전 처리기를 조건부로 넣을 수 있습니까?

#define foo() ??? 

/* 1 */ 
foo(name) 

/* 2 */ 
foo(_) 

원하는 결과 :

/* 1 */ 
int name; 

/* 2 */ 
/*ignore*/ 

는 예, 매크로 악을 알고있다. 나는 호기심 때문에 이것을 주로 요구하고있다.

+12

매크로가 멋지다. –

+2

목적을 설명하거나 더 나은 예를 들어 주시겠습니까? 이 매개 변수는 컴파일시 고정되어야하므로 두 개의 다른 매크로 이름을 사용할 수도 있습니다. – lurker

+0

@mbratch :이 특별한 경우에는 매크로를 사용하여 변수 집합을 정의하지만 일부 변수는 선택 사항이므로 정의하지 않아도됩니다. combinatorial explosion 때문에 여러 개의 매크로 이름이 잘 작동하지 않는다 : 두 개의 변수 이름을 가지고'foo (a, b)','foo (a, _)','foo (_, b)'와' foo (_, _)'. – hugomg

답변

8

아마 다단계 매크로 확장을 시도해보십시오. 이것은 Boost preprocessor/control/if library에서 사용하는 전략입니다.

#define FOO_NAME 1 
#define FOO__ 2 

#define CONC(a,b) a##_##b 
#define FOO(x) CONC(FOO,x) 

C 매크로 확장에서 조건을 검사 할 방법이 없다고 생각합니다.

가장 좋은 점은 # 문자열 연산자를 사용하여 매크로 인수를 문자열 리터럴로 변환 한 다음 런타임 함수를 사용하여 확인하는 것입니다. (당신은 출력 변수 선언에 원하는 곳은, 그러나, 귀하의 경우에는 작동하지 않습니다.) 예를 들어

, 다음 인쇄 "011"

#define FOO(x) (strcmp("NAME", #x) ? 1 : 0) 

main() 
{ 
    printf("%d", FOO(NAME)); 
    printf("%d", FOO(1)); 
    printf("%d", FOO(2)); 
} 

컴파일러는 가능성이 strcmp 비교를 최적화 할

컴파일시에 실제 프로세서 전 조건부를 사용할 수 있었던 것보다 비효율적 일 수 있습니다. 그러나 FOO을 정상적인 함수로 만드는 것이 더 명확하고 효율적일 수 있습니다.

+0

흥미로운 트릭! 그러나 "1"사건에 대한 모든 가능성을 열거 할 필요가없는 방법이 있습니까? 예를 들어'_'면 매크로는 1을 산출하면 2를 산출합니까? – hugomg

+0

원래 질문에 대해 작동하지 않는 제한된 해결 방법으로 답변을 업데이트했습니다. –

+0

불행히도 저는 제 경우 런타임 테스트를 사용할 수 없습니다. 나는 당신이 게임 한 첫 번째 해결책이 내가 얻을 수있는 최선이라고 생각하기 시작했습니다. – hugomg

8

개빈 스미스의 대답에 확장하려면, 당신은 실제로 매크로 확장 내에서 조건을 확인할 수 있습니다

#define FOO_name 1 
#define FOO__ 0 

#define CONC(a,b) a##_##b 

#define IF(c, t, e) CONC(IF, c)(t, e) 
#define IF_0(t, e) e 
#define IF_1(t, e) t 

#define FOO(x) IF(CONC(FOO,x), int x;,) 

FOO(name) // -> int name; 
FOO(_) // -> /*nothing*/ 

당신이 모험을 좋아한다면 당신은 쉽게, 쉼표를 허용하는 IF을 확장하는 등 매크로 확장을 억제 할 수 도우미 매크로.

위와 같이 원하는 모든 이름을 미리 알고 있어야합니다.

관련 문제