How to prevent `#warning` messages from being treated as an error? - c++

I'm trying to compile introduce the -Werror flag in an existing codebase. One of the issues I'm encountering is that at some places #warning is used to display informational messages. These should not be treated as an error.
One solution would be to use #pragma message instead, but this does not seem to be supported by older versions of gcc. (Our build servers use gcc 4.1.2).
Can anyone help me fix this?

In gcc-4.6 and above, you can use -Wno-error=cpp. In at least the clang released with Lion and later, you can use -Wno-error=#warnings. But since your build servers use an ancient gcc, you're probably out of luck there.
In general, pass -fdiagnostics-show-option to have warnings show output like:
test.cc:1:2: warning: #warning hello [-Wcpp]
which tells you a warning flag that controls the warning. In gcc >=4.6 and clang, this is the default, so knowing to pass it may not be too useful anymore.

Locally disable effect of -Werror for #warning as follows:
#pragma GCC diagnostic push
#pragma GCC diagnostic warning "-Wcpp"
#warning Informative message: everything is nice and good!!!
#pragma GCC diagnostic pop
The benefit with this approach is that you can still induce error with #warning elsewhere in the code.

Related

How to enable -fpermissive for a section of code

I have a C single-header library that I would like to use in my C++ project. Normally, I would just include the file and that would be fine because C++ is almost a superset of C. However, this library has a goto that jumps over an initialization, violating the C++ standard.
I can get around this be enabling the -fpermissive compiler flag on GCC, but I want the errors to trigger properly for the rest of my code.
Is there a way I can enable it just for this one header file (perhaps similar to #pragma GCC diagnostic XXX).
There's #pragma GCC optimize "blah" or the function attribute __attribute__((optimize("blah"))) that act like the argument -fblah was given for the rest of that file/that specific function, but it doesn't seem to work with -fpermissive:
$ cat foo.cpp
#pragma GCC optimize "permissive"
void foo(int x) {
}
$ g++-8 -c -Wall -Wextra foo.cpp
foo.cpp:1:22: warning: bad option ‘-fpermissive’ to pragma ‘optimize’ [-Wpragmas]
#pragma GCC optimize "permissive"
^~~~~~~~~~~~
foo.cpp:3:16: warning: bad option ‘-fpermissive’ to attribute ‘optimize’ [-Wattributes]
void foo(int x) {
One option would be to put the function that needs this in a file by itself, and configure your build system to compile just that file with -fpermissive, though that breaks the header-only model. Or fix the code so it doesn't need that option at all.
Per gcc man page:
-fpermissive
Downgrade some diagnostics about nonconformant code from errors to warnings. Thus, using -fpermissive allows some nonconforming code to compile.
So in theory, one can allow a section to compile as permissive using a sequence of gcc warning pragmas:
// Start permissive code
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-result"
#pragma GCC diagnostic ignored "-Wuninitialized"
// .. Other #pragmas
// Permissive Code here.
// Restore normal processing.
#pragma GCC diagnostic pop
One challenge is that there is no published list of errors that will be ignored with -fpermissive (At least I could not find it). One possible approach will be to compile the code, and enter the '#pragma's one at at a time, until the code compiles cleanly.
If one can identify all (or most) of the rules, possible to put them into #include file.
#pragma GCC diagostic push
#include "permissive.h"
// Permissive Code here
#pragma GCC diagostic pop

#pragma(* diagnostic) when mixing Clang analyzers with a GCC compiler

I'm compiling on with GCC on Linux, but CMake is kind enough to produce a Clang compatible compilation database. This means that I can run fancy, modern Clang based tools on my codebase and those tools have perfect knowledge of how each file is to be built (flags, defines, include paths, etc.) So far so good.
But today the Clang based static analysis in my IDE started showing a Clang specific warning. I don't think it particularly matters for my question which warning it is, but it was warning: disabled expansion of recursive macro, generated by -Wdisabled-macro-expansion. This particular macro is provided by a third party, so fixing the warning isn't an option, but I would like to suppress it as it occurs several times in the file in question.
What I'm struggling with is how to suppress the warning in Clang based analysis tools without causing new warnings in the GCC build.
Adding #pragma clang diagnostic ignored "-Wdisabled-macro-expansion" suppresses the warning for Clang tools, but causes GCC to issue warning: ignoring #pragma clang diagnostic [-Wunknown-pragmas].
Similarly, adding #pragma GCC diagnostic ignored "-Wdisabled-macro-expansion" suppresses the Clang warning (because Clang tries to be compatible with GCC diagnostics), but causes GCC to issue warning: unknown option after ‘#pragma GCC diagnostic’ kind [-Wpragmas].
Wrapping either of the above with #ifdef __clang__ makes GCC happy, but doesn't suppress the Clang warning because the tooling is smart enough to know that the code isn't compiled with __clang__, but with __GNUC__ instead.
Is there a way to make a diagnostic #pragma visible to Clang tooling, but not to GCC?
the tooling is smart enough to know that the code isn't compiled with __clang__, but with __GNUC__ instead
If it's reporting a clang-only warning, but does not think that __clang__ is defined, that sounds like a problem with the tooling. If it's trying to be that clever about misrepresenting itself, you may be up a creek... but also you should be complaining to the tool author for creating this situation in the first place.
That said, you could try:
#if defined(__has_warning)
# if __has_warning("-Wdisabled-macro-expansion")
# pragma GCC diagnostic ignored "-Wdisabled-macro-expansion"
# endif
#endif
I'm not sure if this will work... it depends on how hard the tooling is pretending to not be clang (__has_warning is a clang-only extension).

Why "pragma GCC diagnostic push" pop warning in GCC/C++?

#pragma GCC diagnostic push
it pop: warning: expected [error|warning|ignored] after â#pragma GCC diagnosticâ
Why? I use GCC in Linux.
I have one question, if I can't use pop/push, if the ignore only influence the compiled cpp, not influence other cpp? if some other include the cap, if influence it?
#pragma GCC diagnostic push and #pragma GCC diagnostic pop were added in gcc 4.6. You're using an older version.
These pragmas are typically used in conjunction with other #pragma GCC diagnostic directives to suppress, turn on, or turn into an error specific warnings for a small section of your code only. If they're ignored, the changes to warning levels will apply to the rest of the source file rather than just until the next #pragma GCC diagnostic pop. This may not be a problem, or it may be the end of the world; you'll need to understand your code to know for sure.
Either way, you should probably update your compiler. You wouldn't compile C99 with a C89 compiler; don't compile code containing pragmas for gcc 4.6 with gcc 4.4.

In GCC, how can I mute the '-fpermissive' warning?

I am including a file from a third-party library that raises an error that can be downgraded to a warning with -fpermissive. But because I do not want to "pollute" my compilation log with these warnings, I want to completely disable this messages.
So far, I set the -fpermissive option with a diagnostic pragma when including the file; something like:
#pragma GCC diagnostic push
#pragma GCC diagnostic warning "-fpermissive"
#include <third-party-file.h>
#pragma GCC diagnostic pop
Since GCC usually provides both a "positive" and "negative" version of the -f flags, I thought about ignoring the "no-permissive" feature:
#pragma GCC diagnostic ignored "-fno-permissive"
#include <third-party-file.h>
But there does not seem to be a "negative" version of the -fpermissive flag (I am using GCC 4.6.3; but even the version 4.7.0 does not have it).
Can I mimic this behavior?
tldr: You cannot turn off the fpermissive output after GCC 4.7.
Just posting this here so it has more visibility: unfortunately, zwol's answer (while well-intentioned, and potentially helpful to those with older GCC versions) does not work for more recent versions of GCC. From GCC 4.8 and beyond, you cannot turn off the fpermissive output. o11c in his comment to the OP helpfully provides the following bug which tracks this:
Bug 81787. [5/6/7/8 Regression] #pragma GCC diagnostic warning "-fpermissive" no longer
Note that it is in the state "RESOLVED INVALID", so the inability to turn it off is the expected behavior and there are no plans to change it.
One of these ought to do what you wanted:
#pragma GCC diagnostic ignored "-fpermissive"
or
#pragma GCC diagnostic ignored "-pedantic"
"ignored" is how you squelch a diagnostic entirely, and the inverse of -fpermissive is -pedantic, for historical reasons.

Werror ignore certain files

I am wondering if it is possible to have werror in gcc/g++ exclude certain files (ones that I do not have source code to modify) so that I can continue using werror in a uninhibited state.
Use pragma directives with a newer (4.2 I think) version of gcc to turn off -Werror for certain headers prior to including them.
You might want to accept answers for your previous questions.
My only thought is to compile the files you can modify separately with -Werror and then link them with the other object/library files without -Werror.
#Sam Miller already gave the reference documentation about how to do this...
You can temporarily disable -Werror on certain warnings with #pragma GCC diagnostics warning "-W<kind>". For example:
#pragma GCC diagnostic push
# pragma GCC diagnostic warning "-Wreturn-type"
# pragma GCC diagnostic warning "-Wmissing-braces"
# include "legacy-crap.h"
#pragma GCC diagnostic pop
Newer gcc will print the name of the diagnostics category in brackets as part of the the warning/error:
warning-test.c:11:1: warning: return type defaults to ‘int’ [-Wreturn-type]
or
warning-test.c:11:1: error: return type defaults to ‘int’ [-Wreturn-type]
This can be used to accurately select the exact diagnostics which should be treated as warning instead of error during processing of the third party crap you have no power to change. I do not know a short hand to disable all the warnings ("-Wall" will not have desired effect for the above #pragma), but I think it is also good to be explicit here.