'ISO C99在可变参数宏中需要至少一个“...”参数'当专门使用c11和-Wno-variadic-macros时

时间:2017-05-16 01:22:31

标签: gcc macros variadic-macros

我有一个简单的:import random number = random.randint(1,100) # This part works fine guess = input('Guess a number between 1 and 100: ') #Asks question guess = float(guess) tries = 10 while guess != number and tries > 0 : if guess < number: # This part works fine print('Too low') tries = tries - 1 print('You have %s tries left' % (tries)) if guess > number: print('Too high') # This part is also good tries = tries - 1 print('You have %s tries left' % (tries)) if tries == 0: print('You lose!') print('The answer was ' + str(number)) continue if guess == number : print('You win!') # Why doesn't this work? #Python ends at this line if I get it right, but doesn't print: You win! else : guess = input('Try Again: ') guess = float(guess) pass # WHILE* 触发:#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修复此问题(未必测试输出的二进制文件是否有效......)但这似乎有点hacky并且我不完全确定对此的影响。

以下是预期行为的示例:https://stackoverflow.com/a/31327708/5698848

From GNU

#pragma GCC system_header

关于从合法的GNU GCC C代码中阻止此警告/错误的优雅解决方案的任何想法?为什么说我正在使用C99,为什么没有禁用C99警告标志的标志?线看起来像:

-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.

请注意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确实是罪魁祸首。

MCVE

C.C

-pedantic

生成文件

#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;
}

注意:删除学究编译精细 - gcc(Ubuntu 5.4.0-6ubuntu1~16.04.4)5.4.0 20160609

2 个答案:

答案 0 :(得分:6)

在ISO C99和C11中,定义像:

这样的宏
#define log(text, ...)   something

然后任何宏的调用必须至少有2个参数。您的代码在ISO C(所有版本)中格式不正确。

根据the documentation,GCC标志-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 documentation中所述(而不是提供比参数更少的参数的扩展)最小值):

  

GCC长期以来一直支持可变参数宏,并使用不同的语法,允许您像其他参数一样为变量参数命名。这是一个例子:

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

答案 1 :(得分:0)

以下是C99的解决方案:

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