gcc 'ISO C99要求可变参数宏中的“...”至少有一个参数'专门使用c11和-Wno-varidic-macros时[duplicate]

xeufq47z  于 2023-03-02  发布在  Mac
关注(0)|答案(2)|浏览(464)
    • 此问题在此处已有答案**:

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

x6h2sr28

x6h2sr281#

在ISO C99和C11中,当定义如下宏时:

#define log(text, ...)   something

那么任何宏的调用必须至少有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长期以来一直支持可变参数宏,并且使用了一种不同的语法,允许你像给其他参数命名一样给变量参数命名。

#define debug(format, args...) fprintf (stderr, format, args)
7gyucuyw

7gyucuyw2#

以下是C99的解决方案:

#define debug_print(...) \
        do { fprintf(stderr, "%s:%d:%s(): ",__FILE__, __LINE__, __func__);\
             fprintf(stderr, __VA_ARGS__); } while (0)

相关问题