警告 C26431
表达式“expr”的类型已经是
gsl::not_null
。 不要测试它是否为空 (f.23)
C++ Core Guidelines:F.23:使用 not_null<T> 指示“null”不是有效值
指南支持库中的标记类型 gsl::not_null
用于清楚地指示绝不为空指针的值。 如果假设在运行时不成立,则会导致硬故障。 因此,显然,如果表达式计算结果为 gsl::not_null
类型的结果,则无需检查 null。
备注
由于 gsl::not_null
本身是一个瘦指针包装器类,因此该规则实际上跟踪临时变量,这些变量保存从调用到重载转换运算符的结果(该变量返回包含的指针对象)。 此类逻辑使此规则适用于涉及变量的表达式,最终具有 gsl::not_null
类型的结果。 但它当前跳过包含返回 gsl::not_null
的函数调用的表达式。
当前空检查的启发式检测以下上下文:
- 分支条件中的符号表达式,例如
if (p) { ... }
; - 非按位逻辑操作;
- 比较运算,其中一个操作数是计算结果为零的常量表达式。
代码分析名称:DONT_TEST_NOTNULL
示例
不必要的 null 检查显示可疑逻辑:
class type {
public:
template<class T> bool is() const;
template<class T> gsl::not_null<const T*> as() const;
//...
};
class alias_type : public type {
public:
gsl::not_null<const type*> get_underlying_type() const;
gsl::not_null<const type*> get_root_type() const
{
const auto ut = get_underlying_type();
if (ut) // C26431
{
const auto uat = ut->as<alias_type>();
if (uat) // C26431, also incorrect use of API!
return uat->get_root_type();
return ut;
}
return this; // Alias to nothing? Actually, dead code!
}
//...
};
不必要的空检查揭示了有问题的逻辑,已返工:
//...
gsl::not_null<const type*> get_root_type() const
{
const auto ut = get_underlying_type();
if (ut->is<alias_type>())
return ut->as<alias_type>()->get_root_type();
return ut;
}
//...