Temporarily disable gcc warning on redefinition

2020-06-07 04:43发布

问题:

I'm trying to make this work (in GCC 4.6) without barking at me.

#define FOO  ""
#define BAR  ""

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

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

#define EVERYTHING      FOO BAR ...

I am going to have a lot of these. So doing it that way instead of:

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

Saves a lot of code, and makes it more readable. The warning that I get is:

warning: "FOO" redefined [enabled by default]

Is there a way to disable this warning in the code for this particular section? I found Diagnostic Pragmas to disable certain warnings, but I'm not able to find which warning (in this list of Options to Request or Suppress Warnings) that needs to be disabled here.

Anyone know how to do this? Or a different way to avoid having to #else #define all of them to the empty string?

回答1:

This warning comes from file named "cccp.c" in gcc (as of 2.95 version; is this file from "Soviet Russia"?), and it can't be turned off. There is still no option to disable this warning individually even in git head, gcc/libcpp/macro.c file (line 2527 and line 2994 of the same file)

I'll cite sources a bit.

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;

So in your case warn_of_redefinition function will return true. And here is real usage:

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     }

So, there is no any specific option. And answer by Greg is good for this case, just undefine your empty string just before redefinition.



回答2:

Try using #undef:

#define FOO ""

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


回答3:

Or try using if else.

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