调用某个函数未编译时如何触发警告?

问题描述

如果我们写:

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:当您启用优化以便内联函数时 - 忽略警告属性。