- 此问题在此处已有答案**:
GCC compiler warning flag for zero variadic macro arguments(1个答案)
两年前关闭了。
我有一个简单的:#define log(text, ...) fprintf(stderr, "stuff before" text "stuff after", ## __VA_ARGS__);
正在触发:error: ISO C99 requires at least one argument for the "..." in a variadic macro [-Werror]
使用-std=c11
和-Wno-variadic-macros
是否不能修复此错误/警告?
在定义日志之前在头文件中抛出#pragma GCC system_header
可以解决这个问题(没有必要测试输出的二进制文件是否工作...),但这似乎有点笨拙,我不完全确定这会带来什么后果。
下面是一个预期行为的示例:https://stackoverflow.com/a/31327708/5698848
From GNU
-Wvariadic-macros
Warn if variadic macros are used in ISO C90 mode, or if the GNU alternate syntax is used in ISO C99 mode.
This is enabled by either -Wpedantic or -Wtraditional.
To inhibit the warning messages, use -Wno-variadic-macros.
有没有一个优雅的解决方案来阻止这个警告/错误从合法的GNU GCC C代码?为什么它说我正在使用C99,为什么不标记禁用C99的警告工作?行看起来像:gcc -c src/file.c -Wall -Werror -Wextra -pedantic -Wfloat-equal -Wwrite-strings -Wcast-qual -Wunreachable-code -Wcast-align -Wstrict-prototypes -Wundef -Wshadow -Wstrict-aliasing -Wstrict-overflow -Wno-variadic-macros -g3 -std=c11 -O2 -flto -Iinclude/ -MMD -MF depend/file.d -o bin/file.o
请注意,-pedantic
确实是罪魁祸首。
MCVE
c.c
#include <stdio.h>
#include <stdlib.h>
#define log(text, ...) fprintf(stderr, "stuff before" text "stuff after", ## __VA_ARGS__);
int main(void)
{
log("should work, but doesn't");
log("works fine: %s", "yep");
return EXIT_SUCCESS;
}
生成文件
all:
gcc c.c -Wall -Werror -Wextra -pedantic -Wfloat-equal -Wwrite-strings -Wcast-qual -Wunreachable-code -Wcast-align -Wstrict-prototypes -Wundef -Wshadow -Wstrict-aliasing -Wstrict-overflow -Wno-variadic-macros -g3 -std=c11 -O2
注意:删除学究式的编译罚款-gcc(Ubuntu 5. 4. 0 - 6ubuntu1~16. 04. 4)5. 4. 0 20160609
2条答案
按热度按时间x6h2sr281#
在ISO C99和C11中,当定义如下宏时:
那么任何宏的调用必须至少有2个参数。你的代码在ISO C(所有版本)中是格式错误的。
根据文档,GCC标志
-pedantic
表示:发布严格ISO C和ISO C要求的所有警告;拒绝所有使用禁用扩展名的程序,以及其他一些不符合ISO C和ISO C的程序。对于ISO C,遵循由所使用的任何
-std
选项指定的ISO C标准版本。GCC开发人员决定将使用此扩展的代码包含在"一些不遵循ISO C的其他程序"下。如果您想在代码中使用此非标准扩展,则不应使用
-pedantic
标志。GCC开发人员也没有费心修改错误消息的文本,如果你要求C11一致性,那么你可以提交一个补丁。
关于
-Wno-variadic-macros
,文档为:如果在ISO C90模式下使用可变参数宏,或者在ISO C99模式下使用GNU替代语法,则发出警告。
所谓"GNU替代语法",似乎是指在C99之前首先启用可变参数宏的GNU语法,如GCC documentation中所述(而不是提供比最小参数更少参数的扩展):
GCC长期以来一直支持可变参数宏,并且使用了一种不同的语法,允许你像给其他参数命名一样给变量参数命名。
7gyucuyw2#
以下是C99的解决方案: