警告 C26429

符号永远不会进行 nullness 测试,可将其标记为 gsl::not_null

C++ Core GuidelinesF.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();
        // ...
    }
}