1

考虑以下内容 - 我想检查#if #endif是否在代码中的某处定义了令牌。我正在使用一个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;
}
4

2 回答 2

2

如果您使用 just:#if CONCAT(test) == 1它会起作用并且足够了。该语句#if defined(CONCAT(test))不起作用,因为CONCAT(test)被评估为stringtest将被评估为1,并且您不能defined在数字常量上使用。

我想到了一种不同的情况 - 如果我想检查令牌是否是例如。!= 1 如果没有在任何地方定义,则条件将评估为真。因此,未定义的令牌和不等于 1 的令牌之间没有区别。

你可以处理== 0 equal to not defined。所以你可以使用:#if CONCAT(test) != 0 && CONCAT(test) != 1whereCONCAT(test) != 0表示defined(CONCAT(test)). 这是唯一的选择,因为您无法在#ifdefor#if defined()语句中进行宏扩展工作,请参阅与您的问题非常相似的这个问题。


gcc 文档说:

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

通常可以简化为 just #if BUFSIZE >= 1024,因为如果BUFSIZE未定义,它将被解释为具有零值。

如果您使用gcc -E yourSource.cpp.

gcc --帮助:

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

于 2017-06-08T11:54:37.570 回答
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;
}
于 2017-06-08T11:34:06.057 回答