【问题标题】:Misleading performance warning for auto_ptr type passed by value按值传递的 auto_ptr 类型的误导性性能警告
【发布时间】:2016-08-08 10:03:02
【问题描述】:

我正在使用 Cppcheck 1.75 检查我的一个项目,并针对此代码(为清晰起见已简化):

class TJob
{
public:
    TJob(std::auto_ptr<ITask> task);
    // ...
private:
    std::auto_ptr<ITask> m_task;
};

TJob::TJob(
    std::auto_ptr<ITask> task // <-- HERE the performance warning
    ): m_task(task)
{
    trace("TJob ctr");
}

我收到了这个新的性能警告:

Id:passedByValue

总结:函数参数'task'应该通过引用传递。

消息:参数“任务”是按值传递的。它可以作为 (const) 引用传递,这通常更快,并且在 C++ 中被推荐。

这显然是误报。在我看来这是一个错误,因为遵循这个建议会导致一个严重的错误[1],但也许有一个我错过设置的开关,或者我可以提供一些模板来声明 所有权由auto_ptr传递?

我在网上搜索了这个,到目前为止我唯一发现的是 Cppcheck 包含了一些对 Check for invalid usage of STL 的检查,例如

- using auto pointer (auto_ptr)

我知道,auto_ptr 不是最佳选择,但与unique_ptr 不一样吗?会不会是两个检查在这里干扰?

除了使用inline supression 之外,是否可以取消针对这些情况的警告?


编辑:添加了脚注。
[1]没有严重的错误,只是对使用std::auto_ptr的一个误解。我以某种方式将编译时与运行时语义混为一谈:所有权不是通过某种编译时魔法传递的,而是在运行时通过调用“复制”构造函数来传递的。

【问题讨论】:

  • 你的意思是什么建议导致一个严重的错误?所有权仍然会传递给m_task,不是吗?
  • 真的吗?那我真的要深入研究一下了……
  • 如果task是按值传递的,那么对于std::auto_ptr&lt;ITask&gt; my_task(sth); TJob tjob(my_task);,所有权将从my_task传递给参数task,然后传递给成员m_task;如果task通过引用传递,所有权将直接传递给m_task。不是吗?
  • @songyuanyao 是的,确实,我刚刚围绕它构建了一个 littla 项目,使这个(部分)可见。我想,我在某处读到auto_ptr(及其更好的继任者)应该按值传递。我盲目地遵循这一点多么令人尴尬;)(我现在必须在我的小测试中实现复制 ctr 跟踪,才能看到全部真相......)
  • implement copy ctr tracing -- 我的错,这是不可能的,因为这需要进入 auto_ptr 的实现;)所以这必须在调试器中进行跟踪。

标签: c++ auto-ptr cppcheck


【解决方案1】:

当您可以通过引用传递并摊销其中一个副本时,它已正确检测到您正在将值传递给复制构造函数。您的优化器几乎肯定会为您解决“问题”,但没有真正需要依赖它。

我会说你的接口表达在 auto_ptr 的情况下更可取,因为它告诉调用者你正在获取指针,但是我想说核心问题实际上是 auto_ptr 是一个坏公民(可以留在复制操作的无效状态),这就是它被弃用的原因。

【讨论】:

  • because it tells the caller that you are taking the pointer -- 你手头有推荐的参考吗?我记得我在某处读过这篇文章……(嗯,正如我所说,auto_ptr 很糟糕。)
  • auto_ptr 功能类似于 unique_ptr,只有一个所有者。然而,它是从移动构造函数之前的日子开始的,因此复制构造函数用于传递所有权,使复制的对象处于无效状态,这就是为什么 const 复制构造函数已被“删除”。
猜你喜欢
  • 2011-03-24
  • 1970-01-01
  • 2018-09-17
  • 1970-01-01
  • 2021-12-27
  • 2017-03-04
  • 2018-03-25
  • 1970-01-01
相关资源
最近更新 更多