警告 C26411

参数“parameter”是对唯一指针的引用,它永远不会被重新分配或重置,请改用 T*T& (r.33)

通过引用将唯一指针传递给函数时,这意味着其资源可能在函数内部释放或传输。 如果函数仅使用其参数访问资源,则传递原始指针或引用是安全的。 有关详细信息,请参阅 C++ Core Guidelines 规则 R.33:采用 unique_ptr<widget>& 参数来表示函数重新插入小组件。

备注

  • 警告 C26410 的限制也适用于此处。

  • 检测 releasereset 访问唯一指针的启发式方法很简单。 我们仅检测对赋值运算符的调用,以及对命名为 reset(不区分大小写)的函数的调用。 显然,此检测并不涵盖智能指针修改的所有可能情况。 (例如,它不会检测到 std::swap,或者自定义智能指针中任何特殊的非 const 函数)。 我们预计,此警告可能会在自定义类型上产生许多误报,在某些情况下处理标准唯一指针。 我们希望改进启发式方法,因为我们实施更多专注于智能指针的检查。

  • 智能指针通常是模板,这会带来限制。 如果不使用模板代码,则不需要编译器来处理模板代码。 在有限使用智能指针接口的代码中,检查器可能会产生意外结果。 检查器无法正确标识模板类型的语义,因为某些函数可能永远不会使用。 对于标准 std::unique_ptr,通过识别类型的名称来缓解此限制。 将来可能会扩展此分析,以涵盖更知名的智能指针。

  • 执行隐式引用捕获的 Lambda 表达式可能会引发关于引用唯一指针的意外警告。 目前,将报告 lambda 中的所有捕获引用参数,无论它们是否重置。 将来的版本可能会扩展启发式方法,以关联 lambda 字段和 lambda 参数。

代码分析名称:NO_REF_TO_UNIQUE_PTR

示例:不必要的引用

void TraceValid(std::unique_ptr<Slot> &slot)    // C26411
{
    if (!IsDamaged(slot.get()))
        std::cout << *slot.get();
}

void ReleaseValid(std::unique_ptr<Slot> &slot)  // OK
{
    if (!IsDamaged(slot.get()))
        slot.reset(nullptr);
}