Я пытаюсь использовать оператор _Pragma, чтобы игнорировать предупреждение внутри макроса:
#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();
}
}
Но я вижу действительно странное поведение gcc. Если RAII_BLOCK - это макрос без аргументов, он работает должным образом: https://godbolt.org/g/J6RxDV
Но если я добавлю круглые скобки (в моем случае мне действительно нужно передать реальный аргумент), gcc начнет жаловаться: https://godbolt.org/g/tbNtje
Обратите внимание, что clang работает должным образом в обоих случаях. Кто-нибудь знает, как обойти эту проблему (при сохранении теневых предупреждений для остальной части кода)?





Глядя на https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53469 и https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=715271, кажется, что обработка GCC диагностических директив _Pragma в вызовах макросов имела несколько проблем в прошлом, возможно, до сих пор.
Я бы предложил другой путь, который полностью избавит от необходимости переопределять параметры диагностики в определении RAII_BLOCK:
#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();
}
}
Таким образом, все имена переменных защиты вашей области видимости всегда будут уникальными, что избавит вас от необходимости защищать себя от теневых определений.
Спасибо @Nicolas. Я тоже рассматривал этот вариант, но, к сожалению, этот обходной путь у меня не работает, так как мне нужно ссылаться на переменную по имени позже в блоке. В итоге я просто попросил пользователя RAII_BLOCK определить переменную. Это означает, что пользователю нужно будет использовать auto tmp = RAII_BLOCK();, что является более распространенной идиомой в C++.
По крайней мере, объясните, почему голосование против?