【问题标题】:What is the use of a statement with no effect in C++? [duplicate]在 C++ 中没有效果的语句有什么用? [复制]
【发布时间】:2014-07-23 14:02:29
【问题描述】:

在我使用的一个库中,我看到了这段代码:

template<typename T>
void f(SomeTemplatedClass<T> input)
{
    (void)input;
    ...
    use(input); // code that uses input
}

我不知道这段代码是什么意思。如果我将演员表移除为无效,我会得到一个

statement has no effect 

gcc 中的警告。所以我想有人故意这样做,故意添加演员来摆脱警告。

你有没有遇到过无效的声明,但出于某种原因需要它?

编辑:

假设这与模板无关是否安全?例如规避旧的编译器错误等?

【问题讨论】:

  • 这是一种诱使编译器不对未使用的变量发出警告的方法。
  • while (doSomething()) {}
  • 顺便说一句,防止警告的另一种方法就是不命名参数。当您的assert 可能处于活动状态或未处于活动状态时,现有方法非常有用。
  • 哦,这个变量是用在别处的吗?那么我想不出有什么理由要保留这种说法。
  • 除了不给参数命名的注释外,还可以在声明中命名但在定义中不命名。名称(或缺少名称)不需要匹配。

标签: c++ templates


【解决方案1】:

这种构造是欺骗编译器不为未使用的参数发出警告的常用方法。我没有看到它用于任何其他目的。

(void)input;

虽然很常见,但它也是一个非常糟糕的主意。

  • 它高度依赖于平台 -- 它可以在一个编译器上运行,而不是在另一个编译器上运行。
  • 没有必要。总是有更好的方法来处理未使用的参数。现代方法是简单地省略参数名称。
  • 如果代码更改并且现在使用参数,它可能会被抛在后面(就像这里的情况一样)。
  • 它可能会适得其反。一些编译器可能会将其视为无效。

根据 C++ 标准 N3936 S5.4/11:

在某些情况下,表达式仅出于其副作用而出现。这样的表达式称为弃值表达式。对表达式求值并丢弃其值。

编译器有权观察到没有副作用,因此该构造至少值得警告。根据@chris 的说法,MSVC 就是其中一种编译器。

【讨论】:

  • 注意:某些参数(或变量)可能只在 Debug 中使用,而不是在 Release 中使用,在这种情况下不命名它们根本不是一种选择。在这种情况下,您的建议是什么?我看到了 Herb Sutter 的一个技巧:template &lt;typename T&gt; void unused_variable(T&amp;&amp;) {},然后是 unused_variable(input);,尽管当人们使用它时可能会产生误导。
  • Release 代码应该尽可能干净并且没有这些东西。调试代码应采用不强加此类要求的策略。考虑将此作为一个单独的问题提出。
猜你喜欢
  • 1970-01-01
  • 2015-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多