GCC: trying to use -Werror or -pedantic using pragmas

58 views Asked by At

In files being compiled using gcc (several .c and .cpp files) I have currently something like:

#if defined(__GNUC__) && !defined(__clang__)
    #pragma GCC diagnostic warning "-Wall"
#endif

The purpose of specifying inline options instead of just using the command line is to control after which points I'm interesting in going more strict (e.g., after the #include list).

It works fine. I then tried to add -Wextra with:

#if defined(__GNUC__) && !defined(__clang__)
    #pragma GCC diagnostic warning "-Wall -Wextra"
#endif

It fails. Apparently, you can't use more than one option in a single pragma, and you have to use several lines instead:

#if defined(__GNUC__) && !defined(__clang__)
    #pragma GCC diagnostic warning "-Wall"
    #pragma GCC diagnostic warning "-Wextra"
#endif
  • Q1: Is there a way to specify several options inline?

Next, I tried to add -Werror and -pedantic, and neither using diagnostic warning nor diagnostic error works. Example:

    #pragma GCC diagnostic error "-Werror"

fails with: warning: ‘-Werror’ is not an option that controls warnings. How can I solve this? which other alternatives there's besides diagnostic [warning|error]? What about -pedantic or -pedantic-errors? Because I'm aware pedantic is mostly related with standard compliance rather than diagnostic control and I don't know if I can even specify it inline.

2

There are 2 answers

3
Christian Stieber On BEST ANSWER

Well, you can't. It's just how it is.

You can turn specific warnings on or off, or turn them into errors, but you can't do everything with #pragma as you have noticed. Note that "-Wpedantic" can still be controlled.

In general, I still put most options into the build file, including -Werror. I don't think it's such a great idea to keep switching around warnings for sections of code.

In the (rare-ish) case that some header gives warnings, I use pragmas to disable them for that header -- push the settings, disable warning, include header, pop the settings. This leads to constructs like

#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wshadow"
#endif

#include "External/ProtoPuf/message.h"

#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif

However, I don't use stuff like this for my own code -- instead, I fix the warnings in the code, or remove the warning from the build system if it's too annoying.

0
Lundin On

Is there a way to specify several options inline?

If you for some reason has to write out the pragma on a single line, because you are making a function-like macro or similar, you can use the _Pragma operator which is similar to #pragma but can be used a bit more flexibly. It works exactly the same, just squeeze what you would type after #pragma in a string literal. And if what you typed happened to be a string literal, then add escape sequences \".

Example:

#include <stdio.h>

#define CHECK_ALL_THE_STUFF                      \
  _Pragma ("GCC diagnostic push")                \
  _Pragma ("GCC diagnostic warning \"-Wall\"")   \
  _Pragma ("GCC diagnostic warning \"-Wextra\"") \

#define YOU_ARE_NO_FUN_ANYMORE                   \
  _Pragma ("GCC diagnostic pop")                 \

int main() 
{
  CHECK_ALL_THE_STUFF
    printf("%d\n", 1.0f);
  YOU_ARE_NO_FUN_ANYMORE
  
  printf("%d\n", 1.0f);
}

This gives me a warning for the first printf line

warning: format '%d' expects argument of type 'int', but argument 2 has type 'double'

But not for the second one.


Next, I tried to add -Werror and -pedantic, and neither using diagnostic warning nor diagnostic error works.

Not all compiler options can be used like this, simple as that. Basically only the -W... ones work. See https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html

As noted in another answer by @Christian Stieber, -Wpedantic is a work-around to enable that particular option.