无法在条件编译块中解析类似函数的宏

时间:2017-06-08 11:28:16

标签: c macros c-preprocessor conditional-compilation define-syntax

请考虑以下内容 - 我想与#if #endif核实是否a 令牌在代码中的某处定义。 我正在使用一个CONCAT(input)宏,它应该粘合我要检查的令牌的常量和更改部分。

不幸的是,下面介绍的方法会导致编译错误:

error: missing binary operator before token "("

我找到了可以放在#if #endif块中的表达式:

https://gcc.gnu.org/onlinedocs/cpp/If.html#If

显然它表明:

宏。在实际计算表达式的值之前,表达式中的所有宏都会被扩展。

事实证明(CONCAT(test))应该得到解决,但事实并非如此。

是否有任何解决方法允许在条件编译块中正确解析串联令牌名称?

#include <stdio.h>

#define CONCAT(input) string##input
#define stringtest 1

int main(void) 
{
    #if defined(CONCAT(test)) && (CONCAT(test)==1)
        printf("OK");
    #else
        printf("NOT");
    #endif

    return 0;
}

2 个答案:

答案 0 :(得分:2)

如果您只使用:#if CONCAT(test) == 1它将起作用并且是有效的。 声明#if defined(CONCAT(test))执行,因为CONCAT(test)将评估为stringtest,评估结果为1,您无法使用defined {1}}关于数值常数。

  

我想到了另一种情况 - 如果我想检查令牌是否是例如,该怎么办? != 1然后,如果未在任何地方定义,则条件将评估为true。因此,未定义的令牌与不同于1的令牌之间没有区别。

您可以处理== 0 相等 to not defined。因此,您可以使用#if CONCAT(test) != 0 && CONCAT(test) != 1,其中CONCAT(test) != 0表示defined(CONCAT(test))。这是唯一的选择,因为您无法在#ifdef#if defined()语句中进行宏扩展工作,请参阅此question,这与您的非常相似。

gcc documentation说:

  

这样的条件:       #if defined BUFSIZE && BUFSIZE >= 1024

     

通常可以简化为#if BUFSIZE >= 1024,因为如果未定义BUFSIZE,则会将其解释为值为零。

如果使用gcc -E yourSource.cpp检查宏扩展,也会有所帮助。

gcc --help:

  

-E仅预处理;不编译,汇编或链接

答案 1 :(得分:1)

你做不到。只能使用文字。

你应该直接检查宏:

#include <stdio.h>

#define CONCAT(input) string##input
#define stringtest 1

int main(void) {
    #if stringtest  == 1
        printf("OK");
    #else
        printf("NOT");
    #endif
    return 0;
}

由于您不需要定义检查,您可以这样使用:

#define CONCAT(input) string##input
#define stringtest 1

int main(void) {
    #if CONCAT(test) == 1
        printf("OK");
    #else
        printf("NOT");
    #endif
    return 0;
}