On 01/11/2011 02:10 AM, Jonathan Wakely wrote:
... elision by patrick...
I use something like this:
#if ((__GNUC__*100)+__GNUC_MINOR__)>= 406
If the macros aren't defined they will evaluate to zero.
Thanks, I was thinking of something similar, but this is nothing
compared to the awesomeness that follows.
... more elision by patrick ...
I wrote this last week, which tames some of the ugliness:
#if ((__GNUC__ * 100) + __GNUC_MINOR__)>= 405
# define GCC_DIAG_DO_PRAGMA(x) _Pragma (#x)
# define GCC_DIAG_PRAGMA(x) GCC_DIAG_DO_PRAGMA(GCC diagnostic x)
# if ((__GNUC__ * 100) + __GNUC_MINOR__)>= 406
# define GCC_DIAG_OFF(x) GCC_DIAG_PRAGMA(push) \
GCC_DIAG_PRAGMA(ignored x)
# define GCC_DIAG_ON(x) GCC_DIAG_PRAGMA(pop)
# else
# define GCC_DIAG_OFF(x) GCC_DIAG_PRAGMA(ignored x)
# define GCC_DIAG_ON(x) GCC_DIAG_PRAGMA(warning x)
# endif
#else
# define GCC_DIAG_OFF(x)
# define GCC_DIAG_ON(x)
#endif
This is great, and supports the use to turn warnings off wonderfully.
From reading this I assume that 4.5 is the point at which the pragmas
were able to be put at any scope instead of just file scope. Is this
also true for #pragma GCC system_header as well, that prior to 4.5 it
had to be at file scope, but from 4.6 forward it can be at any scope?
Also, can I steal, with attribution of course, GCC_DIAG_OFF/ON(x)?
Also is there an implementation define nesting limit to #pragma GCC
diagnostic push as there is in the similar microsoft compiler #pragma
warning push? (Their limit is about 50 I think). That seems like it
would be plenty, but it's been hit in boost code that was doing tmp.
Also, what if there are too many pops? Is that an error, or ignored?
Also did you consider making them so that you could use them like:
GCC_DIAG_OFF(sign-compare)
if (a< b) {
GCC_DIAG_ON(sign-compare)
std::cout<< "a<b\n";
}
just to save the four keystrokes that would be common to all? Something
like:
#define str(s) #s
#define joinstr(x,y) str(x ## y)
#if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 405
# define GCC_DIAG_DO_PRAGMA(x) _Pragma (#x)
# define GCC_DIAG_PRAGMA(x) GCC_DIAG_DO_PRAGMA(GCC diagnostic x)
# if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406
# define GCC_DIAG_OFF(x) GCC_DIAG_PRAGMA(push) \
GCC_DIAG_PRAGMA(ignored joinstr(-W,x))
# define GCC_DIAG_ON(x) GCC_DIAG_PRAGMA(pop)
# else
# define GCC_DIAG_OFF(x) GCC_DIAG_PRAGMA(ignored joinstr(-W,x))
# define GCC_DIAG_ON(x) GCC_DIAG_PRAGMA(warning joinstr(-W,x))
# endif
#else
# define GCC_DIAG_OFF(x)
# define GCC_DIAG_ON(x)
#endif
I know it's a little silly, but I get carried away wanting the compiler
to do stuff for me.
Patrick
That gives convenient macros which are used like so:
GCC_DIAG_OFF("-Wsign-compare")
if (a< b) {
GCC_DIAG_ON("-Wsign-compare")
std::cout<< "a<b\n";
}
The macros use push/pop for 4.6+, or for 4.5 they just change the
behaviour to "ignored" then back to "warning". They expand to
nothing for older versions of GCC or for non-GCC compilers.
The 4.5 behaviour is wrong if e.g. -Werror=sign-compare was being
used, because GCC_DIAG_ON re-enables a warning not an error. For my
purposes that was sufficient, it's probably not acceptable for library
code.
I've been using this for super-strict compilations with a modified GCC
that has extra warnings I've added. One of my extra warnings has too
many false positives, so I really needed to disable some known
warnings I wasn't going to fix.
For these super-strict builds, I need to temporarily disable warnings
in third-party libraries which I can't or don't want to change (Boost
in particular.) To do this I include them with -isystem instead of -I,
which has the same effect as adding the system_header pragma to them.
That allows me to make warnings fatal with -Werror without having to
worry about errors in code I don't own.