将函数属性应用于析构函数
是否可以将属性应用于析构函数? 示例:
#if defined (__GNUC__) && !defined(__clang__)
# define TEST_PRE_ATTR [[deprecated]] __attribute__((deprecated))
# define TEST_POST_ATTR __attribute__((error("test")))
#elif defined(_MSC_VER) && !defined(__clang__)
# define TEST_PRE_ATTR [[deprecated]] __declspec(deprecated)
# define TEST_POST_ATTR
#elif defined (__clang__)
# define TEST_PRE_ATTR [[deprecated]] __attribute__((deprecated))
# define TEST_POST_ATTR __attribute__((diagnose_if(true, "test", "error")))
#endif
struct Foo {
//TEST_PRE_ATTR
void bar()
//TEST_POST_ATTR
{}
TEST_PRE_ATTR
~Foo()
TEST_POST_ATTR
= default;
};
int main() {
Foo* f = new Foo();
f->bar();
delete f;
return 0;
}
GCC、Clang 和 MSVC 会忽略Foo::~Foo. 如果将相同的属性应用于Foo::bar,它们会按预期创建警告。根据标准和cppreference,析构函数的语法应该允许前导和尾随属性。(我想这不会产生任何语法错误的事实证实了这一点。)
在我的特定情况下,我有一个 UndefinedBehaviorSanitizer 构建(-fsanitize=undefined),我试图__attribute__((no_sanitize("undefined")))在析构函数上使用来抑制来自上游库的错误(我无法控制)。但是,我无法抑制该错误,因为所有编译器似乎都忽略了此属性。
我有一种感觉,答案将是非常不令人满意的,例如“允许编译器出于任何原因忽略任何属性”。如果是这种情况,有人可以提出解决方法吗?我宁愿不做一些像禁用整个目标的 UBSan 那样粗暴的事情。