选择性地抑制未使用 lambda 的“未使用变量”警告

Posted

技术标签:

【中文标题】选择性地抑制未使用 lambda 的“未使用变量”警告【英文标题】:Selectively suppress "unused variable" warnings for unused lambdas 【发布时间】:2013-11-19 15:47:40 【问题描述】:

是否有任何方法可以抑制特定文件、命名空间或特定变量的“未使用变量”警告?

我问是因为我有一个包含大量 lambda 函数的命名空间。有些现在没有使用,但可能会及时使用。如果这些是常规的免费功能,那么如果有些未使用,我不会收到警告。但是,由于它们是 lambda,我最终会收到一堆编译器警告。

我确实想使用编译器标志来删除所有此类警告,通常情况下,让编译器捕获未使用的变量非常有用。然而,一堆关于未使用的实用程序函数的警告会给其他有用的信息增加噪音。

【问题讨论】:

你用的是什么编译器? 取决于编译器,有一些#pragma 叮当声。 . . . . . . . 我没用过clang,所以不知道。我用过谷歌,这看起来可能有用 - useyourloaf.com/blog/2011/09/20/… 【参考方案1】:

我想到了两种方法。首先,大多数构建环境都启用了 per-source 编译器标志,因此您应该能够仅针对定义了所有这些 lambda 的单个文件关闭该警告。

然后有一种通用方法可以消除对单个变量的此类警告:使用它,但不要真正用它做任何事情。在某些编译器上,这可以通过简单的强制转换为 void 来实现:

auto x = /* ... */;
(void) x;

但更有效的是定义一个简单的函数,使其看起来(对于编译器)好像使用了变量:

template <class T>
void ignore_unused(T&)  

//later...
auto x = /* ... */;
ignore_unused(x);

注意这个参数没有名字,所以编译器不会抱怨那个一个没有被使用。

这个想法很常见:对变量做一些有效地不进行操作但使发出“未使用变量”警告的静态分析器静音的操作。

Boost也有类似的功能,boost::ignore_unused_variable_warning()

有关详细信息,请参阅Herb Sutter's blog。

【讨论】:

【参考方案2】:

在 C++ 中,您可以 static_castvoid 的任何内容。

如果这种类型转换不会产生任何副作用或人们可能会问的值,那么它有什么用?

准确地告诉编译器一个对象以可移植的方式“使用”。

所以,

auto x =  /*...*/;
static_cast<void>(x);

【讨论】:

这很讽刺,因为这样做你根本没有使用它。 static_cast&lt;void&gt;(x) won't work on many compilers【参考方案3】:

Lambda 是 just syntactic sugar for functors。函子是一种对象(具有operator() 重载的对象)。因此,如果该变量(对象)未被使用,编译器会发出警告。

我推荐使用块注释方法来使编译器静音;)。除此之外,在一般情况下,您无法选择性地干净地使编译器静音。

注意,如果你有更具体的情况,比如在函数中传递参数,你可以make the argument nameless不使用它。您可以做的另一件事是put a (void)var reference somewhere in your code(虽然这是作弊;现在您已经引用了它!)。最后,如果您的编译器支持它(全能的 GCC 支持),您可以尝试使用 the __attribute__((unused)) preprocessor directive(对于 Clang 使用 [[gnu::unused]])。

根据您的情况,这些建议可能有帮助,也可能没有帮助。

【讨论】:

您说“Lambda 只是函子的语法糖”。我以前也这么认为,但我现在不太确定了。考虑:auto f = [](int x)return x+1;; for (int i = 0; i &lt; n; ++i) f = [f](int x) return f(f(x)); 。对函子的转换并不简单(我猜 f 的按值捕获需要实现为 unique_ptr 或等效项,而不仅仅是一个普通的成员变量)。 我对你的第一段感到困惑。听起来你在说“lambdas 非常像函子;因此未使用的 lambda 会像未使用的函子一样收到警告”。但未使用的仿函数不会收到警告。见***.com/questions/5302848/…【参考方案4】:

如何将 lambdas 隐藏在生成器中。这样,除非使用它们,否则它们甚至不会被创建。所以而不是:

auto add_one= [](int x) return x + 1  ;

用途:

std::function<int(int)> gen_addone(void)

    static auto l_= [](int x) return x + 1 ;  ;
    return l_ ;
   

对不起,你得等到 c++1y 才能自动推断返回类型。

【讨论】:

以上是关于选择性地抑制未使用 lambda 的“未使用变量”警告的主要内容,如果未能解决你的问题,请参考以下文章

如何最好地消除有关未使用变量的警告?

gcc编译选项-Wall(编译警告:未使用变量变量未初始化类型转换等)

Prometheus 选择性地抑制警报

选择性地抑制输出python [重复]

抑制 lambda 上的 Microsoft.Reliability 警告

使用 lambda 对 std::map 进行排序