我试图使用_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在两种情况下都按预期工作。有谁知道如何解决这个问题(同时保留其余代码的阴影警告)?
答案 0 :(得分:2)
看看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();
}
}
这样,所有范围保护变量名称将始终是唯一的,从而消除了保护自己免受阴影定义的必要性。