【问题标题】:Variadic macros: Different output for identical code可变参数宏:相同代码的不同输出
【发布时间】:2018-12-04 13:22:40
【问题描述】:

我在 CLion 中创建了一个项目来测试宏。 我创建了一个宏来计算给它的参数数量。 首先,这个宏给了我有效的输出(0 表示没有 args,1 表示一个 args,2 表示两个 args ...)。 但是,我不知道发生了什么,我的宏只是以某种方式无效。也许是因为很多 SIG_ILL 失败,当我从它的声明范围之外调用函数时未定义的行为,我在一个表达式中声明了函数。

我试图在 C++ 中实现方法和 new 运算符,但是通过 C 预处理器,这最终成功,直到突然我用于计算参数的宏失败。 现在它给出 1 表示没有 args,1 表示一个 args,2 表示两个 args。并且在编译时会发生此错误,而 CLion 的“内联当前用法”功能仍然向我显示,在没有 args 的情况下调用此宏应扩展为 0。

这是这个项目,只是简单的 main.c:

#include <stdio.h>

#define Macro_argument_20(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
_11, _12, _13, _14, _15, _16, _17, _18, _19, _20, ...) _20

#define Macro_argumentsAmount(ARGS...) \
Macro_argument_20("dummy", ##ARGS, 18, 17, 16, 15, 14, 13, 12, 11,10,\
9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

int main() {
    printf("%i", Macro_argumentsAmount());

    return 0;
}

我不知道并创建了一个新项目来看看会发生什么,所以我复制/粘贴了以前的 CMakeLists.txt 和代码并得到了预期的输出。

所以现在我有两个相同的项目,但输出不同。 有谁知道怎么回事?

更新:

仍然在通过

检查源代码的预处理版本时
gcc -E main.c -std=c17  -fplan9-extensions  -Werror -Wno-implicit - 
Wno-error=variadic-macros -Wno-error=implicit-fallthrough

我在两个项目中都看到了以下主要内容(尽管其中一个打印了 0):

# 9 "main.c"
int main() {
 printf("%i", 1);

 return 0;
}

【问题讨论】:

  • 请不要发布截图。发布显示问题的Minimal, Complete, and Verifiable example,以便人们可以复制、粘贴、编译、运行。
  • 抱歉,我找不到隐藏图片的选项。这个问题看起来难以置信,所以我想给出证据。
  • Macro_argumentsAmount() 是零参数还是一个空参数?为什么你会期望一个胜过另一个?您希望Macro_argumentsAmount(,) 得到什么结果?
  • @Chris, Macro_argumentsAmount() 必须扩展为 0,这就是当 ARGS 在这种上下文中导致空参数时 ## 运算符的工作方式。至于Macro_argumentsAmount(,),这应该给出 2,因为您将空参数显式转发给宏,它只是扩展为单个逗号,这意味着在它的两侧都有两个参数。空论也是论据。我可以通过对每个参数进行字符串化并询问它的长度来检查这个问题,但是这样的前锋对我来说似乎太荒谬和不必要了。
  • “纯C”是什么意思? ##ARGS 是非标准 gcc 扩展,此代码无法使用严格的 C 编译器编译。

标签: c gcc undefined-behavior preprocessor


【解决方案1】:

-std=c17 选项添加到编译器时,会禁用##ARGS 的GCC 逗号吞咽扩展。

请改用-std=gnu17 来启用 GNU 扩展以及 c2017 功能。

【讨论】:

  • 哦,我刚刚注意到了,在玩cmake编译器选项的时候,谢谢,这很意外
猜你喜欢
  • 2017-05-21
  • 2018-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-24
相关资源
最近更新 更多