问题描述
如果我们写:
void foo() {
#warning "Danger Will Robinson!"
}
我们会在编译 foo()
时收到警告。现在,我想要做的是让编译不发出警告,而是在 foo()
被调用时发出警告。
使用 g++ 和/或 clang++ 可以吗?
注意:这个问题有点类似于 this one,关于将函数标记为“已弃用”(a-la C++14 的 [[deprecated]]
属性)。然而,这是一个不同的语义。我不希望人们认为我的函数已被弃用,而是收到自定义警告。
解决方法
C++11 添加了 _Pragma
,它类似于 #pragma
,但宏可以扩展到它。所以,你可以制作一个宏,扩展到这个警告和功能:
#include <cstdio>
void foo() {
std::puts("foo is called!");
}
#define foo(...) _Pragma("message \"Danger Will Robinson!\"") \
foo(__VA_ARGS__)
int main() {
foo();
}
这种方法的主要问题是它不会考虑重载并警告名称为 foo
的任何函数。
@StoryTeller 在评论中的建议,在 GCC 中部分有效:
__attribute__ ((warning ("Danger Will Robinson!")))
void foo() { }
int bar() {
const int x = 123;
foo();
return x;
}
为什么是“部分”?正如@StoryTeller 所说:
如果调用位于已消除的分支上,则死代码消除可以消除警告
查看 This GodBolt example:当您启用优化以便内联函数时 - 忽略警告属性。