警告 C26429
符号永远不会进行 nullness 测试,可将其标记为
gsl::not_null
。
C++ Core Guidelines:F.23:使用 not_null<T>
指示“null”不是有效值
通常的做法是使用断言来对指针值的有效性进行假设。 问题是,断言不会通过接口公开假设(例如返回类型或参数)。 维护断言并使其与其他代码更改保持同步也更有难度。 建议使用指南支持库中的 gsl::not_null
来标记永远不应具有 null 值的资源。 规则 USE_NOTNULL
有助于识别省略 null 检查的位置,因此可以更新为使用 gsl::not_null
。
备注
此规则的逻辑要求代码取消引用指针变量,以便证明 nullness 检查(或强制执行非 null 值)是合理的。 因此,仅当指针被取消引用并且从未测试为 null 时才会发出警告。
当前的实现仅处理普通指针(或其别名),并且不检测智能指针,尽管 gsl::not_null
也可以应用于智能指针。
在以下上下文中使用变量时,该变量被标记为已进行 null 检查:
- 作为分支条件中的符号表达式,例如
if (p) { ... }
; - 非按位逻辑操作;
- 比较运算,其中一个操作数是计算结果为零的常量表达式。
该规则没有完整的数据流跟踪。 在使用间接检查(例如,中间变量保留 null 值,稍后在比较中使用)的情况下可能会产生不正确的结果。
代码分析名称:USE_NOTNULL
示例
隐藏的预期:
using client_collection = gsl::span<client*>;
// ...
void keep_alive(const connection *connection) // C26429
{
const client_collection clients = connection->get_clients();
for (ptrdiff_t i = 0; i < clients.size(); i++)
{
auto client = clients[i]; // C26429
client->send_heartbeat();
// ...
}
}
gsl::not_null
阐明的隐藏预期:
using client_collection = gsl::span<gsl::not_null<client*>>;
// ...
void keep_alive(gsl::not_null<const connection*> connection)
{
const client_collection clients = connection->get_clients();
for (ptrdiff_t i = 0; i < clients.size(); i++)
{
auto client = clients[i];
client->send_heartbeat();
// ...
}
}