【问题标题】:Is there a compiler warning is Visual Studio 2013 to detect references copied instead of assigned by reference是否有编译器警告是 Visual Studio 2013 来检测复制而不是通过引用分配的引用
【发布时间】:2018-10-20 10:12:57
【问题描述】:

特殊情况是,在一次大型重构之后,一位同事发生了变化

Foo & foo = DoSomething();

auto foo = DoSomething();

在哪里

Foo & DoSomething();

这导致了一个问题,即 foo 是通过复制而不是通过引用分配的。我们抓到了一个案子。我很好奇是否有编译器警告来检测上述代码导致的错误类型。

** 编辑 **

以下所有答案都包含有关应该做什么或不应该做什么的有用且有效的建议。需要明确的是,我正在寻找一些关于损坏发生后可以做什么的建议。一个很少使用的编译警告会很好。最后我们只是查看了代码差异,看看是否不止一次犯了同样的错误。

【问题讨论】:

  • 已删除复制构造函数。反正很少需要。
  • 很难警告什么是完全有效的代码。我同意 VTT,顺便说一句。删除复制 ctor,它会标记您所寻找的内容(可能更多,但您必须顺其自然)。
  • 没什么可警告的,所以没有。
  • 根据我的经验;这种警告通常由单元测试提供。你有单元测试,不是吗?
  • 另一种方法是查看重构的差异并寻找缺失的&

标签: c++ visual-studio-2010 pass-by-reference pass-by-value auto


【解决方案1】:

auto 的错误使用对性能非常不利。我已经对它的用法进行了多次讨论。

我的经验法则是尽可能使用auto && 变量。这遵循模板规则,成为转发引用。

可用于引用、常量引用和按值返回。 通过将其用作默认值,autoauto & 清楚地表明您想要一个副本或者您想要一个可变引用。

也就是说,我不熟悉这种结构的编译器警告。我确实找到了一个看起来类似的 clang-tidy 检查:https://clang.llvm.org/extra/clang-tidy/checks/performance-unnecessary-copy-initialization.html

【讨论】:

    【解决方案2】:

    你的同事是个很淘气的男孩。首先请注意,Visual C++ 2013 不是 C++11 编译器,尽管它确实实现了一些 C++11 标准。值得注意的是,constexpr 不见了。

    非正式地说,auto 确实自动包含 &,所以它们本质上发生了变化

    Foo & foo = DoSomething();
    

    Foo foo = DoSomething();
    

    这集中体现了在没有适当单元测试的情况下错误重构的危险。

    正确的做法是保持代码不变。但是如果你公司的文化是所有新的和闪亮的东西都必须进入一个项目,那么最好的办法就是使用

    auto&& foo = DoSomething();
    

    要生成一组一次性的编译器警告,为什么不(暂时)删除复制构造函数并尝试构建项目?:

    Foo(const Foo&) = delete;
    

    【讨论】:

      【解决方案3】:

      一个好的经验法则可能是使用 decltype(auto) 而不是 auto 并为此进行心理训练。

      在提供的示例中,它将使foo 的类型成为对Foo 的引用。

      【讨论】:

      • 或者只是不要 AAA :P
      • @Rakete1111 我自己不喜欢 AAA,但有时类型太复杂而无法指定。 auto p = std::make_pair()std::pair<Y, Z> p = ... 更有意义
      • 我完全同意,但据我了解,OP 的同事到处都将类型更改为 auto :)
      • decltype(auto) 不是一个好的解决方案,因为它不能与其他类型说明符组合,因此声明 auto const & x{...}; 会变成 decltype(auto) x{::std::as_const(…)}
      • @VTT 在这种特殊情况下,根据提供的代码不需要它。当需要时,肯定会使用其他东西,但有意识地使用。记录一下,在很多情况下,删除复制构造函数也不是最好的主意。
      猜你喜欢
      • 2014-04-25
      • 1970-01-01
      • 1970-01-01
      • 2017-04-04
      • 2016-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-03
      相关资源
      最近更新 更多