How to put a warning disable pragma inside a macro gcc - c++

I need to disable a warning that originates inside the macro '__LOG_W' in following code. To do that, I wrapped this macro inside another macro 'LOG_W' and disabled the warning '-Wold-style-cast' with in that. Then in the code I used the LOG_W instead.
However I still get the warning and unable to find out why. Any pointers appreciated.
#define LOG_W(expr)\
_Pragma("GCC diagnostic push")\
_Pragma("GCC diagnostic ignored \"-Wold-style-cast\"")\
__LOG_W(DEF, UNKNOWN, expr);\
_Pragma("GCC diagnostic pop")

Related

Unknown pragma ignored: warning [duplicate]

What's the closest GCC equivalent to this MSVC preprocessor code?
#pragma warning( push ) // Save the current warning state.
#pragma warning( disable : 4723 ) // C4723: potential divide by 0
// Code which would generate warning 4723.
#pragma warning( pop ) // Restore warnings to previous state.
We have code in commonly included headers which we do not want to generate a specific warning for. However, we want files which include those headers to continue to generate that warning (if the project has that warning enabled).
This is possible in GCC since version 4.6, or around June 2010 in the trunk.
Here's an example:
#pragma GCC diagnostic push
#pragma GCC diagnostic error "-Wuninitialized"
foo(a); /* error is given for this one */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
foo(b); /* no diagnostic for this one */
#pragma GCC diagnostic pop
foo(c); /* error is given for this one */
#pragma GCC diagnostic pop
foo(d); /* depends on command line options */
The closest thing is the GCC diagnostic pragma, #pragma GCC diagnostic [warning|error|ignored] "-Wwhatever". It isn't very close to what you want, and see the link for details and caveats.
I've done something similar. For third-party code, I didn't want to see any warnings at all. So, rather than specify -I/path/to/libfoo/include, I used -isystem /path/to/libfoo/include. This makes the compiler treat those header files as "system headers" for the purpose of warnings, and so long as you don't enable -Wsystem-headers, you're mostly safe. I've still seen a few warnings leak out of there, but it cuts down on most of the junk.
Note that this only helps you if you can isolate the offending code by include-directory. If it's just a subset of your own project, or intermixed with other code, you're out of luck.
This is an expansion to Matt Joiner's answer.
If you don't want to spawn pragmas all over your code, you can use the _Pragma operator:
#ifdef __GNUC__
# define DIAGNOSTIC_ERROR(w) _Pragma("GCC diagnostic error \"" w "\"")
# define DIAGNOSTIC_IGNORE(w) _Pragma("GCC diagnostic ignore \"" w "\"")
# define DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
# define DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
#endif
// (...)
DIAGNOSTIC_ERROR("-Wuninitialized")
foo(a); // Error
DIAGNOSTIC_PUSH
DIAGNOSTIC_IGNORE("-Wuninitialized")
foo(a); // No error
DIAGNOSTIC_POP
foo(a); // Error

Concise way to disable specific warning instances in Clang

Suppose there is some warning in my code, e.g. that Clang has added padding to a struct. I am find with that particular instance and I want to mark it as "Noted; don't warn me about this instance again".
Is there a way to do this that isn't insanely verbose (i.e. #pragma clang diagnostic push etc)? Ideally something like a comment on the same line as the warning, something like this:
// clang(-Wno-padded)
To be clear, I only want to suppress one specific instance of the warning (which normally requires #pragma diagnostic push/pop), not all warnings in the file.
As described in the Controlling Diagnostics via Pragmas article it would be:
#pragma clang diagnostic ignored "-Wpadded"
If you want to suppress a warning in a certain chunk of code (be it a single line of code or multiple statements) then you need to utilize the push / pop mechanism:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
// your code for which the warning gets suppressed
#pragma clang diagnostic pop
// not suppressed here
If you have some include file where you can put a macro definition like this:
#define DO_PRAGMA(x) _Pragma(#x)
#define NOWARN(warnoption, ...) \
DO_PRAGMA(GCC diagnostic push) \
DO_PRAGMA(GCC diagnostic ignored #warnoption) \
__VA_ARGS__ \
DO_PRAGMA(GCC diagnostic pop)
Then you can disable a warning within your code like this:
NOWARN(-Wpadded,
// your code for which the warning gets suppressed
)
Example: https://godbolt.org/z/oW87ej
Slightly off-topic note:
gcc does not allow GCC diagnostic .... pragmas within expressions. So something like this:
#define MY_MYCRO(type) NOWARN(-Wpadded, sizeof(struct{char c; type t;}))
int myval = MY_MYCRO(int);
will produce a error in gcc and won't compile. Note: Using clang diagnostic .... pragmas will not produce an error in gcc (but also doesn't disable the warning in gcc).

Avoid superfluous warnings when compiling Qt code with ccache / clang

I am having the same problem as this guy.
Compiling with clang and ccache I get this warning everytime it encounters a Q_OBJECT:
warning: explicitly assigning value of variable of type 'int' to itself [-Wself-assign]
This only happens when using ccache, compiling the same code with clang alone works fine.
There seems to be a similar issue with macro expansions where the suggested solution is to set the environment variable
CCACHE_CPP2=yes
Unfortunately, this does not seems to fix my issue, or maybe I'm doing it wrong.
I have tried:
Building from command line with
CCACHE_CPP2=yes ninja
export CCACHE_CPP2=yes
ninja
Building from Qt Creator, adding CCACHE_CPP2 to "Build Environment"
Is there anything else I can do to fix this macro expansion issue? I specifically do not want to disable warnings globally (because that's bad) or locally (because that means wrapping all macros in compiler-specific boilerplate).
Try adding -Wno-self-assign to the CPP flags . It should allow you to disable self-assign errors :
CXXFLAGS= $(CXXFLAGS) -Wno-self-assign
or
CPPFLAGS=$(CPPFLAGS) -Wno-self-assign
Forgive me for not having clang to test this with, but I felt I should help anyway. Expanding on Marek's answer, there's the possibility of placing the pragma inside another macro expansion. It's a very ugly solution, but that way you only need to define the macro once, instead of spawning pragmas all over your code base.
#define WARN int&x = x;
#define NO_WARN _Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wuninitialized\"") \
WARN \
_Pragma("GCC diagnostic pop")
int main(){
NO_WARN
}
As you can see, I tested it with gcc(I have no means of testing with clang right now), but that should work fine in clang by substituting "GCC" with "clang" inside the macro(and using -Wself_assign). Applying to your problem(pseudocode):
#ifdef clang
#define MY_Q_OBJECT _Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wself-assign\"") \
Q_OBJECT \
_Pragma("clang diagnostic pop")
#else
#define MY_Q_OBJECT Q_OBJECT
#endif
class A{
MY_Q_OBJECT // Unfortunately you still need to replace Q_OBJECT on your classes
}
Another ugly downside is that, at least on gcc, I had to run the preprocessor twice for it to work. Can't tell if the same is necessary for clang.
IMO ignoring this warning globally is not a problem. It warns about dummy code, not about potential logic errors caused by typo. That is why I've voted up #MichaelCMS answer.
But there is a way to disable warning only is some section of code:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wself-assign"
Q_OBJECT
#pragma clang diagnostic pop
This should do the trick (if I didn't mess up the flag name), but I don't like it, to much boiler plate macros.

Suppress -Wtautological-compare warning

I have some code like
Q_ASSERT(value_which_is_always_smaller_than_4 < 4)
where Q_ASSERT is Qts assert macro. Now clang, when seeing this warns me about it, because the comparison is always true. Nice that it can detect this, but that's the point of the assert statement. Can I somehow suppress the warning, but only in assert statements? I'd still liked to be warned in other places.
You can define a new macro to wrap Q_ASSERT and automatically silence the warning using #pragma clang diagnostic ignored:
#define STR(x) #x
#define PRAGMA(x) _Pragma(STR(x))
#define MY_ASSERT(x) PRAGMA(clang diagnostic push) \
PRAGMA(clang diagnostic ignored "-Wtautological-compare") \
Q_ASSERT(x) \
PRAGMA(clang diagnostic pop)
Now just doing
MY_ASSERT(3<4)
should not produce a warning.
You can disable it for the entire file by adding -Wno-tautological-compare to the Clang command line (after flags such as -Wall that turn warnings on). The disadvantage of this method is that the warning is now disabled everywhere in that translation unit, not just for the Q_ASSERT(...) macro instances.
Another, more tedious but fine grained, method is to wrap every instance of the macro that generates this warning with the following:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
Q_ASSERT(value_which_is_always_smaller_than_4 < 4)
#pragma clang diagnostic pop

Selectively disable GCC warnings for only part of a translation unit

What's the closest GCC equivalent to this MSVC preprocessor code?
#pragma warning( push ) // Save the current warning state.
#pragma warning( disable : 4723 ) // C4723: potential divide by 0
// Code which would generate warning 4723.
#pragma warning( pop ) // Restore warnings to previous state.
We have code in commonly included headers which we do not want to generate a specific warning for. However, we want files which include those headers to continue to generate that warning (if the project has that warning enabled).
This is possible in GCC since version 4.6, or around June 2010 in the trunk.
Here's an example:
#pragma GCC diagnostic push
#pragma GCC diagnostic error "-Wuninitialized"
foo(a); /* error is given for this one */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
foo(b); /* no diagnostic for this one */
#pragma GCC diagnostic pop
foo(c); /* error is given for this one */
#pragma GCC diagnostic pop
foo(d); /* depends on command line options */
The closest thing is the GCC diagnostic pragma, #pragma GCC diagnostic [warning|error|ignored] "-Wwhatever". It isn't very close to what you want, and see the link for details and caveats.
I've done something similar. For third-party code, I didn't want to see any warnings at all. So, rather than specify -I/path/to/libfoo/include, I used -isystem /path/to/libfoo/include. This makes the compiler treat those header files as "system headers" for the purpose of warnings, and so long as you don't enable -Wsystem-headers, you're mostly safe. I've still seen a few warnings leak out of there, but it cuts down on most of the junk.
Note that this only helps you if you can isolate the offending code by include-directory. If it's just a subset of your own project, or intermixed with other code, you're out of luck.
This is an expansion to Matt Joiner's answer.
If you don't want to spawn pragmas all over your code, you can use the _Pragma operator:
#ifdef __GNUC__
# define DIAGNOSTIC_ERROR(w) _Pragma("GCC diagnostic error \"" w "\"")
# define DIAGNOSTIC_IGNORE(w) _Pragma("GCC diagnostic ignore \"" w "\"")
# define DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
# define DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
#endif
// (...)
DIAGNOSTIC_ERROR("-Wuninitialized")
foo(a); // Error
DIAGNOSTIC_PUSH
DIAGNOSTIC_IGNORE("-Wuninitialized")
foo(a); // No error
DIAGNOSTIC_POP
foo(a); // Error