2011-10-17 19 views
9

Bir belirteci başka bir şeyle birleştirilmeden önce değerlendirmek istiyorum. "Problem" yedek listesi yerine daha makro adları açısından yeniden muayene edilir önce standart bir bağımsız değişken ile ilgili değildir (yedek listesinde bir ## ön-işleme, her simge örneğiÖnişlemci belirtecini ## birleştirmeden önce değerlendirin

olarak davranışını belirler olmasıdır) silinir ve önceki ön işlem belirteci, aşağıdaki ön işlem belirteci ile birleştirilir. Aşağıdaki örnekte dolayısıyla

,

#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 

son beyan

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], }; 

genişletilir ve ben değil

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], }; 

istediğim gibi. Bunu üreten makroları tanımlamanın bir yolu var mı? Makroların ilk kümesi yapar, ancak önek çoğaltmasından kaçınmak ve bunu yalnızca bir kez tanımlamak istiyorum. Yani öneki #define ile ayarlamak ve makroların bunu kullanmasına izin vermek mümkün mü?

+0

olası yinelenen [C önişlemcisine ile iki kez bitiştirmek ve "arg ## deki gibi bir makro genişletmek için nasıl \ _ # # MACRO "?] (Http://stackoverflow.com/questions/1489932/how-to-concatenate-twice-with-the-c-preprocessor-and-expand-a-macro-as-in-arg) Lütfen deneyin Örnekleri en aza indirmek için :-) –

cevap

4

Bunun için ikinci seviye genişletmeyi kullanabilirsiniz, örn.

#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

Evet, bunu beğendim. Eski makroları değiştirmeye ve başkaları için muhtemel birleştirme problemleri yaratmaya gerek yok. Ayrıca, çift ekspantyonun sezgisel olarak anlaşılmasa bile, aynı önekin her iki yerde de kullanıldığı aşikardır. – hlovdal

11

You can use a macro for concatenation

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

gibi bu daha sonra çalışır

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

Böyle şeylerin neden iki seviye gerektirdiğini asla anlamadım. Makro genişleme için ilk seviye ve ikinci birleştirme için ikinci olan mı? – ijustlovemath