jak*_*ake 3 macros gcc variadic-macros
我有一个简单的:#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在定义日志之前抛出头文件修复了这个问题(没有必要测试输出的二进制文件是否有效......)但这看起来有点hacky,我不完全确定这个的后果.
以下是预期行为的示例:https://stackoverflow.com/a/31327708/5698848
-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.
Run Code Online (Sandbox Code Playgroud)
想要从合法的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确实是罪魁祸首.
CC
#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;
}
Run Code Online (Sandbox Code Playgroud)
Makefile文件
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
Run Code Online (Sandbox Code Playgroud)
注意:删除学究编译精细 - gcc(Ubuntu 5.4.0-6ubuntu1~16.04.4)5.4.0 20160609
在ISO C99和C11中,当您定义一个宏时:
#define log(text, ...) something
Run Code Online (Sandbox Code Playgroud)
那么宏的任何调用必须至少有2个参数.您的代码在ISO C(所有版本)中格式不正确.
-pedantic根据文件,海湾合作委员会的旗帜意味着:
发出严格的ISO C和ISO C++要求的所有警告; 拒绝所有使用禁止扩展的程序,以及其他一些不遵循ISO C和ISO C++的程序.对于ISO C,遵循由
-std所使用的任何选项指定的ISO C标准的版本.
GCC开发人员决定在"其他一些不遵循ISO C的程序"下使用此扩展程序包含代码.如果要在代码中使用此非标准扩展,则不应使用该-pedantic标志.
如果您请求C11一致性,GCC开发人员也不打算修改错误消息的文本以说"ISO C11禁止...".如果这涉及到你,那么也许你可以提交补丁.
关于-Wno-variadic-macros,文件是:
如果在ISO C90模式下使用可变参数宏,或者在ISO C99模式下使用GNU替代语法,则发出警告.
通过"GNU替代语法",它们似乎意味着在C99之前首先启用可变参数宏的GNU语法,如GCC文档中所述 (而不是提供少于最小值的参数的扩展):
GCC长期以来一直支持可变参数宏,并使用不同的语法,允许您像任何其他参数一样为变量参数赋予名称.这是一个例子:
Run Code Online (Sandbox Code Playgroud)#define debug(format, args...) fprintf (stderr, format, args)