【问题标题】:Cannot resolve function-like macro inside conditional compilation block无法解析条件编译块内的类似函数的宏
【发布时间】:2017-11-10 02:15:44
【问题描述】:

考虑以下 - 我想检查 #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;
}

【问题讨论】:

  • 我认为你不能那样做。

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


【解决方案1】:

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

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

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


gcc documentation 说:

这样写的条件: #if defined BUFSIZE &amp;&amp; BUFSIZE &gt;= 1024

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

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

gcc --help:

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

【讨论】:

  • 感谢您提供更简单的建议。我想到了一种不同的情况 - 如果我想检查令牌是否是例如。 != 1 然后,如果它没有在任何地方定义,则条件将评估为真。所以 token 未定义和 token 不等于 1 之间没有区别。你对这种情况有什么建议吗?
  • 我编辑了我的答案以满足您的其他问题,我希望作为替代方案有所帮助。
【解决方案2】:

你不能那样做。只能使用文字。

你应该直接检查宏:

#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;
}

【讨论】:

  • 顺便说一句,这是多余的。 #if stringtest == 1 就够了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-22
  • 1970-01-01
  • 2012-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多