C宏数据库-在另一个宏中测试宏函数的参数

时间:2018-10-25 20:17:15

标签: c templates macros

我正在尝试创建一个包含一系列C函数宏的C宏表,如果C函数宏的另一个参数满足某些条件,则将其变成C函数宏的一个参数的列表。

例如,在FancyPantsTable.h中定义一个数据库:

#if defined (MY_FANCY_PANTS_TABLE)
FANCY_PANTS_DB( A, 123)
FANCY_PANTS_DB( B, 456)
FANCY_PANTS_DB( C, 456)
FANCY_PANTS_DB( D, 123)
#endif

然后,在FancyPants.c中,将FancyPantsTable.h导入要创建列表的所有位置。

#define numberSought 456

uint8 my456Array [] = {

            #define FANCY_PANTS_DB( aUint8, num ) #if  ( num == numberSought sought ) aUint8, #endif
            #define MY_FANCY_PANTS_TABLE
            #include "FancyPantsTable.h"
            #undef MY_FANCY_PANTS_TABLE
};

#define numberSought 123

uint8 my123Array [] = {

            #define FANCY_PANTS_DB( aUint8, num ) #if  ( num == numberSought sought ) aUint8, #endif
            #define MY_FANCY_PANTS_TABLE
            #include "FancyPantsTable.h"
            #undef MY_FANCY_PANTS_TABLE
};

C宏模板很难调试。在#if处,我得到一个错误,提示“期望宏参数名称。”

这就是我正在做的事情。我该如何解决?

2 个答案:

答案 0 :(得分:1)

请记住,宏不能定义另一个宏。所以像

#define FANCY_PANTS_DB( aUint8, num ) #if  ( num == numberSought sought ) aUint8, #endif

无效。预处理器只能通过一次,因此您不能使用这样的东西。

如果我没记错的话,可以根据需要这样写:

FancyPantsTable.h:

#if MY_FANCY_PANTS_TABLE==123
 A, 
#endif
#if MY_FANCY_PANTS_TABLE==456
 B, 
 C, 
#endif
#if MY_FANCY_PANTS_TABLE==123
 D, 
#endif

FancyPants.c:

#define MY_FANCY_PANTS_TABLE 456

uint8 my456Array [] = {
            #include "FancyPantsTable.h"
             };

#undef MY_FANCY_PANTS_TABLE
#define MY_FANCY_PANTS_TABLE 123

uint8 my123Array [] = {
            #include "FancyPantsTable.h"
            };
#undef MY_FANCY_PANTS_TABLE

即使我不确定这是否是您想要的。

答案 1 :(得分:0)

由于花式表头文件必须知道所有数字,因此请为每个数字定义一个默认宏,以使参数无效。

#if defined (MY_FANCY_PANTS_TABLE)

// PREAMBLE
#ifndef FANCY_PANTS_DB_ENTRY_123
#define FANCY_PANTS_DB_ENTRY_123(...) 
#endif

#ifndef FANCY_PANTS_DB_ENTRY_456
#define FANCY_PANTS_DB_ENTRY_456(...) 
#endif

#define FANCY_PANTS_DB(X, Y) \
        FANCY_PANTS_DB_ENTRY_##Y(X,)

FANCY_PANTS_DB( A, 123)
FANCY_PANTS_DB( B, 456)
FANCY_PANTS_DB( C, 456)
FANCY_PANTS_DB( D, 123)

// EPILOGUE
#undef FANCY_PANTS_DB_ENTRY_123
#undef FANCY_PANTS_DB_ENTRY_456
#undef FANCY_PANTS_DB

#endif

然后,在包含文件之前,定义适当的入口宏以发出其参数。

uint8 my456Array [] = {
            #define FANCY_PANTS_DB_ENTRY_456(...) __VA_ARGS__
            #define MY_FANCY_PANTS_TABLE
            #include "FancyPantsTable.h"
            #undef MY_FANCY_PANTS_TABLE
};

uint8 my123Array [] = {
            #define FANCY_PANTS_DB_ENTRY_123(...) __VA_ARGS__
            #define MY_FANCY_PANTS_TABLE
            #include "FancyPantsTable.h"
            #undef MY_FANCY_PANTS_TABLE
};

您可能可以将头文件的PREAMBLE和EPILOGUE部分隐藏到由脚本生成的单独的头文件中。