警告 C26411
参数“parameter”是对唯一指针的引用,它永远不会被重新分配或重置,请改用
T*
或T&
(r.33)
通过引用将唯一指针传递给函数时,这意味着其资源可能在函数内部释放或传输。 如果函数仅使用其参数访问资源,则传递原始指针或引用是安全的。 有关详细信息,请参阅 C++ Core Guidelines 规则 R.33:采用 unique_ptr<widget>& 参数来表示函数重新插入小组件。
备注
警告 C26410 的限制也适用于此处。
检测
release
或reset
访问唯一指针的启发式方法很简单。 我们仅检测对赋值运算符的调用,以及对命名为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);
}