'ISO C99 requires at least one argument for the "..." in a variadic macro' 专门使用 c11 和 -Wno-variadic-macros 时
'ISO C99 requires at least one argument for the "..." in a variadic macro' When specifically using c11 and -Wno-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
修复了这个问题(不一定测试输出的二进制文件是否有效......)但这似乎有点老套,我并不完全确定这个的后果。
这是预期行为的示例:
-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
在 ISO C99 和 C11 中,当您定义如下宏时:
#define log(text, ...) something
那么对宏的任何调用都必须至少有 2 个参数。您的代码在 ISO C(所有版本)中的格式不正确。
GCC 标志 -pedantic
,根据 the documentation,表示:
Issue all the warnings demanded by strict ISO C and ISO C++; reject all programs that use forbidden extensions, and some other programs that do not follow ISO C and ISO C++. For ISO C, follows the version of the ISO C standard specified by any -std
option used.
GCC 开发人员决定在 "some other programs that do not follow ISO C" 下包含使用此扩展的代码。如果你想在你的代码中使用这个非标准扩展,那么你不应该使用 -pedantic
标志。
如果您请求 C11 一致性,GCC 开发人员也不会费心修改错误消息的文本以说 "ISO C11 forbids..."。如果这与您有关,那么也许您可以提交一个补丁。
关于-Wno-variadic-macros
,文档是:
Warn if variadic macros are used in ISO C90 mode, or if the GNU alternate syntax is used in ISO C99 mode.
"GNU alternate syntax",它们似乎是指在 C99 之前首先启用可变参数宏的 GNU 语法,如 GCC documentation 中所述(而不是提供更少参数的扩展比最小值):
GCC has long supported variadic macros, and used a different syntax that allowed you to give a name to the variable arguments just like any other argument. Here is an example:
#define debug(format, args...) fprintf (stderr, format, args)
这是 C99 的解决方案:
#define debug_print(...) \
do { fprintf(stderr, "%s:%d:%s(): ",__FILE__, __LINE__, __func__);\
fprintf(stderr, __VA_ARGS__); } while (0)
我有一个简单的:#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
修复了这个问题(不一定测试输出的二进制文件是否有效......)但这似乎有点老套,我并不完全确定这个的后果。
这是预期行为的示例:
-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
在 ISO C99 和 C11 中,当您定义如下宏时:
#define log(text, ...) something
那么对宏的任何调用都必须至少有 2 个参数。您的代码在 ISO C(所有版本)中的格式不正确。
GCC 标志 -pedantic
,根据 the documentation,表示:
Issue all the warnings demanded by strict ISO C and ISO C++; reject all programs that use forbidden extensions, and some other programs that do not follow ISO C and ISO C++. For ISO C, follows the version of the ISO C standard specified by any
-std
option used.
GCC 开发人员决定在 "some other programs that do not follow ISO C" 下包含使用此扩展的代码。如果你想在你的代码中使用这个非标准扩展,那么你不应该使用 -pedantic
标志。
如果您请求 C11 一致性,GCC 开发人员也不会费心修改错误消息的文本以说 "ISO C11 forbids..."。如果这与您有关,那么也许您可以提交一个补丁。
关于-Wno-variadic-macros
,文档是:
Warn if variadic macros are used in ISO C90 mode, or if the GNU alternate syntax is used in ISO C99 mode.
"GNU alternate syntax",它们似乎是指在 C99 之前首先启用可变参数宏的 GNU 语法,如 GCC documentation 中所述(而不是提供更少参数的扩展比最小值):
GCC has long supported variadic macros, and used a different syntax that allowed you to give a name to the variable arguments just like any other argument. Here is an example:
#define debug(format, args...) fprintf (stderr, format, args)
这是 C99 的解决方案:
#define debug_print(...) \
do { fprintf(stderr, "%s:%d:%s(): ",__FILE__, __LINE__, __func__);\
fprintf(stderr, __VA_ARGS__); } while (0)