2011-10-17 1 views
9

토큰이 다른 것으로 연결되기 전에 토큰을 평가하고 싶습니다. 은 "문제는"대체 목록을 대체 에 더 많은 매크로 이름을 재검토하기 전에 표준 인수에서하지 (교체 목록에서는, ## 전처리 토큰의 각 인스턴스를## 연결 전에 전 처리기 토큰을 평가하십시오.

등의 동작을 지정하는 것입니다)가 삭제되고 앞선 사전 처리 토큰이 다음 전처리 토큰과 연결됩니다. 다음의 예에 따라서

,

#include <stdlib.h> 

struct xy { 
    int x; 
    int y; 
}; 

struct something { 
    char * s; 
    void *ptr; 
    int size; 
    struct xy *xys; 
}; 
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) 

#define DECLARE_XY_BEGIN(prefix) \ 
struct xy prefix ## _xy_table[] = { 

#define XY(x, y) {x, y}, 

#define DECLARE_XY_END(prefix) \ 
    {0, 0} \ 
}; \ 
struct something prefix ## _something = { \ 
    "", NULL, \ 
    ARRAY_SIZE(prefix ## _xy_table), \ 
    &(prefix ## _xy_table)[0], \ 
}; 

DECLARE_XY_BEGIN(linear1) 
    XY(0, 0) 
    XY(1, 1) 
    XY(2, 2) 
    XY(3, 3) 
DECLARE_XY_END(linear1) 


#define DECLARE_XY_BEGIN_V2() \ 
struct xy MYPREFIX ## _xy_table[] = { 

#define DECLARE_XY_END_V2() \ 
    {0, 0} \ 
}; \ 
struct something MYPREFIX ## _something = { \ 
    "", NULL, \ 
    ARRAY_SIZE(MYPREFIX ## _xy_table), \ 
    &(MYPREFIX ## _xy_table)[0], \ 
}; 

#define MYPREFIX linear2 
DECLARE_XY_BEGIN_V2() 
    XY(0, 0) 
    XY(2, 1) 
    XY(4, 2) 
    XY(6, 3) 
DECLARE_XY_END_V2() 
#undef MYPREFIX 

마지막 선언은

struct xy MYPREFIX_xy_table[] = { 
{0, 0}, 
{2, 1}, 
{4, 2}, 
{6, 3}, 
{0, 0} }; struct something MYPREFIX_something = { "", 0, (sizeof(MYPREFIX_xy_table)/sizeof((MYPREFIX_xy_table)[0])), &(MYPREFIX_xy_table)[0], }; 

으로 확장되고 난에하지

struct xy linear2_xy_table[] = { 
{0, 0}, 
{2, 1}, 
{4, 2}, 
{6, 3}, 
{0, 0} }; struct something linear2_something = { "", 0, (sizeof(linear2_xy_table)/sizeof((linear2_xy_table)[0])), &(linear2_xy_table)[0], }; 

을 원하는 것처럼. 이것을 생성하는 매크로를 정의 할 수있는 방법이 있습니까? 매크로의 첫 번째 집합이 있지만 접두사 중복을 피하고 한 번만 정의해야합니다. 그래서 접두어를 #define으로 설정하고 매크로가이를 사용하도록 할 수 있습니까?

+0

가능한 중복 [C 전처리 두 번 연결할 및 "인수 ##에서와 같이 매크로를 확장하는 방법 \ _ # # MACRO "?] (http://stackoverflow.com/questions/1489932/how-to-concatenate-twice-with-the-c-preprocessor-and-expand-a-macro-as-in-arg) 시도해보십시오. 예를 최소화하기 위해 :-) –

답변

4

두 번째 레벨 확장을 사용할 수 있습니다 (예 :

#define XY_HLP1(a) DECLARE_XY_BEGIN(a) 
#define XY_HLP2(a) DECLARE_XY_END(a) 
#define DECLARE_XY_BEGIN_V2() XY_HLP1(MYPREFIX) 
#define DECLARE_XY_END_V2() XY_HLP2(MYPREFIX) 
+0

예, 저는 이것을 좋아합니다. 이전 매크로를 변경하고 다른 매크로 병합 문제를 만들 필요가 없습니다. 또한 이중 확장이 직관적으로 이해하지 못할 수도있는 경우에도 동일한 접두사가 두 위치에서 모두 사용됩니다. – hlovdal

11

You can use a macro for concatenation

#define CONCAT_(A, B) A ## B 
#define CONCAT(A, B) CONCAT_(A, B) 

처럼이 다음 작동

#define A One 
#define B Two 
CONCAT(A, B) // Results in: OneTwo 
+1

그런 것들이 왜 두 단계가 필요한지 나는 결코 이해하지 못합니다. 매크로 확장의 첫 번째 레벨이고 실제 연결을위한 두 번째 레벨입니까? – ijustlovemath