Reputation: 1515
I'm trying to use the _Pragma operator in order to ignore a warning inside a macro:
#define RAII_BLOCK() \
_Pragma("GCC diagnostic push \"-Wshadow\"") \
_Pragma("GCC diagnostic ignored \"-Wshadow\"") \
auto a = RAII(); \
_Pragma("GCC diagnostic pop")
void foo() {
RAII_BLOCK();
{
RAII_BLOCK();
}
}
But I see really odd behavior from gcc. If RAII_BLOCK
is a macro with no arguments it works as expected: https://godbolt.org/g/J6RxDV
But if I add the parenthesis (in my use case I actually need to pass a real argument), gcc starts complaining: https://godbolt.org/g/tbNtje
Note that clang works as expected in both cases. Does anyone know how to get around this issue (while keeping the shadow warnings for the rest of the code)?
Upvotes: 2
Views: 1058
Reputation: 488
Looking at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53469 and https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=715271, it seems that GCC's handling of _Pragma
diagnostic directives in macro invocations had a few issues in the past, possibly still.
I would suggest another route, which is to entirely avoid having to override diagnostics settings in the RAII_BLOCK definition:
#include <iostream>
using namespace std;
struct RAII{
RAII() { cout << "acquired" << endl; }
~RAII() { cout << "released" << endl; }
};
#define CONCAT_(a, b) a ## b
#define CONCAT(a, b) CONCAT_(a, b)
#define RAII_BLOCK() auto CONCAT(a,__COUNTER__) = RAII();
void foo() {
RAII_BLOCK();
{
RAII_BLOCK();
}
}
This way, all your scope guard variable names will always be unique, removing the necessity for protecting yourself from shadow definitions.
Upvotes: 3