C预处理器获取带连接的选项列表

时间:2014-12-19 12:04:21

标签: c gcc c-preprocessor avr-gcc

我想使用 C 预处理器生成一个依赖于其他编译选项的选项列表。

(或者我可以问我如何将多个字符串连接成一个定义?)

这里我有一个例子(avr-gcc)用于我想要做的但它不起作用:

// C preprocessor get option list with concatenation

#include <stdint.h>

// #define CompileOption1 1        // first compile option
#define CompileOption2 1    // second compile option

static char options[20] = " ";    // string of options

/**********************************************************/
void exec_command (uint8_t opt) {
    switch (opt) {
    #define MAIN_COMMAND "FirstDefinition"
#ifdef CompileOption1
        case 'b':
        #define MAIN_COMMAND (MAIN_COMMAND ## "b")
            break;
#endif
#ifdef CompileOption2
        case 't':
        #define MAIN_COMMAND MAIN_COMMAND ## t
            break;
        case 'u':
#endif
        case 's':
//         #define MAIN_COMMAND (MAIN_COMMAND ## "s")
            break;
        case 'v':    
//         #define MAIN_COMMAND (MAIN_COMMAND ## v)
            break;
        case 'r':
//         #define MAIN_COMMAND "Blabla"
            break;
    }
//     #define MAIN_COMMAND "Testomat"
    strcpy(options, MAIN_COMMAND);
}

/**********************************************************/
int main(void) {

    while(1) {
        exec_command('v');
//         doing something with the options here
    }
} 

我想获得正确的&#34;选项列表&#34;保存在字符串中。

编译显示这些错误:

main.c: In function ‘exec_command’:
main.c:21:0: warning: "MAIN_COMMAND" redefined [enabled by default]
main.c:13:0: note: this is the location of the previous definition
main.c:36:2: warning: implicit declaration of function ‘strcpy’ [-Wimplicit-function-declaration]
main.c:36:2: warning: incompatible implicit declaration of built-in function ‘strcpy’ [enabled by default]
main.c:36:1: error: ‘MAIN_COMMANDt’ undeclared (first use in this function)
main.c:36:1: note: each undeclared identifier is reported only once for each function it appears in

正如你所看到的,我尝试了许多不同的连接方法,但没有一种方法可以工作。

也许有另一种更好的方法来生成这样的字符串?

2 个答案:

答案 0 :(得分:1)

我认为您需要的代码更像是:

#define B_OPT
#define T_OPT
#define S_OPT
#define V_OPT

void exec_command(uint8_t opt)
{
    switch (opt)
    {
    #define MAIN_COMMAND "FirstDefinition"
#ifdef CompileOption1
    case 'b':
        #undef  B_OPT
        #define B_OPT "b"
        break;
#endif
#ifdef CompileOption2
    case 't':
        #undef  T_OPT
        #define T_OPT "t"
        break;
    case 'u':
#endif
    case 's':
        #undef  S_OPT
        #define S_OPT "s"
        break;
    case 'v':    
        #undef  V_OPT
        #define V_OPT "v"
        break;
    …
    }
    strcpy(options, MAIN_COMMAND B_OPT T_OPT S_OPT V_OPT);
#undef B_OPT
#undef T_OPT
#undef S_OPT
#undef V_OPT
}

我不确定你是否会#undef MAIN_COMMAND。在一个级别上,最后四个#undef操作不是必需的。您也可以根据需要重新定义MAIN_COMMAND的值;确切的要求并不清楚。

关键是要为要连接到最终字符串的组件定义宏值,然后依靠字符串连接从相关部分中生成一个字符串。

我并不完全相信你所做的事情是个好主意,但我认为这是达到你想要的目标的一种方式。

答案 1 :(得分:0)

你需要2个宏

#define MAIN_COMMAND "FirstDefinition"

然后

#define MAKE_COMMAND(command) MAIN_COMMAND#command

您可以阅读here了解更多信息,使用它需要执行此操作

const char *command;
case t:
    command = MAKE_COMMAND(t);
    break;

并且在函数结束时,假设您已声明options并且它适合生成的字符串,请执行

strcpy(options, command);