暂时禁用gcc对重定义的警告

36

我正在尝试使这个(在GCC 4.6中)不出错。

#define FOO  ""
#define BAR  ""

#if ....
    #define FOO    "Foo, good sir"
#endif

#if ...
    #define BAR    "Bar, my lady"
#endif
....

#define EVERYTHING      FOO BAR ...

我将会有很多这样的东西。所以这样做而不是:

#if ...
    #define FOO    "Foo"
#else
    #define FOO    ""
#endif

节省了很多代码,使其更易读。我得到的警告是:

警告:“FOO”被重新定义[默认情况下启用]

有没有办法在此特定部分的代码中禁用此警告?我发现诊断编译指示可以禁用某些警告,但我无法找到需要在这里禁用的警告(在请求或抑制警告的选项列表中)。
有人知道如何做到这一点吗?或者有避免不得不将它们全部#else #define为空字符串的不同方法吗?

12
你可以使用-Wp,-w来禁用预处理器警告 - osgx
2
这个警告来自于gcc中名为“cccp.c”的苏联俄罗斯文件(截至2.95版本),它无法关闭。仍然没有选项可以单独禁用此警告即使在git head、gcc/libcpp/macro.c中(以及同一文件的第2994行)。 - osgx
@osgx 如果您将该评论作为答案,我愿意接受它。 - Jonathon Reinhart
9
谢谢你,匿名的投票者!我很高兴我的三年半前的问题没有满足你的要求! - Jonathon Reinhart
3个回答

47
尝试使用 #undef
#define FOO ""

#if ....
    #undef FOO
    #define FOO "Foo, good sir"
#endif

11

这个警告来自gcc中名为"cccp.c"的文件(截至2.95版本;这个文件来自“苏联俄罗斯”吗?),它无法关闭。目前即使在git head中仍然没有选项可以单独禁用此警告,gcc/libcpp/macro.c 文件 (同一文件的第2527行和第2994行)。

我稍微引用了一些来源。

2525 /* Returns nonzero if a macro redefinition warning is required.  */
2526 static bool
2527 warn_of_redefinition (cpp_reader *pfile, cpp_hashnode *node,
2528                       const cpp_macro *macro2)
2529 {
...
2537   /* Suppress warnings for builtins that lack the NODE_WARN flag.  */
..
2545   /* Redefinitions of conditional (context-sensitive) macros, on
2546      the other hand, must be allowed silently.  */
...
2550   /* Redefinition of a macro is allowed if and only if the old and new
2551      definitions are the same.  (6.10.3 paragraph 2).  */
...
2561   /* Check parameter spellings.  */
...
2566   /* Check the replacement text or tokens.  */
...
2573   for (i = 0; i < macro1->count; i++)
2574     if (!_cpp_equiv_tokens (&macro1->exp.tokens[i], &macro2->exp.tokens[i]))
2575       return true;

在你的情况下,warn_of_redefinition函数将返回true。这是一个真实的用法示例:

2989   if (node->type == NT_MACRO)
2990     {
2991       if (CPP_OPTION (pfile, warn_unused_macros))
2992         _cpp_warn_if_unused_macro (pfile, node, NULL);
2993 
2994       if (warn_of_redefinition (pfile, node, macro))
2995         {
2996           const int reason = (node->flags & NODE_BUILTIN)
2997                              ? CPP_W_BUILTIN_MACRO_REDEFINED : CPP_W_NONE;
2998           bool warned;
2999 
3000           warned = cpp_pedwarning_with_line (pfile, reason,
3001                                              pfile->directive_line, 0,
3002                                              "\"%s\" redefined",
3003                                              NODE_NAME (node));
3004 
3005           if (warned && node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
3006             cpp_error_with_line (pfile, CPP_DL_NOTE,
3007                                  node->value.macro->line, 0,
3008                          "this is the location of the previous definition");
3009         }
3010     }

所以,没有任何具体的选项。Greg的回答对于这种情况很好,只需要在重新定义之前取消定义你的空字符串即可。


19
在苏联,宏定义了你! - einpoklum

0

或尝试使用 if else。

#if ...
#   define FOO "Foo, doof sir"
#else
#   define FOO ""
#endif

1
这对我不起作用(framework-arduinoespressif8266 3.20704.0)。 虽然 #undef 能够解决问题。 - hypers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接