警告 C26448

如果打算执行最终操作,请考虑使用 gsl::finally (gsl.util)

C++ Core Guidelines:GSL.util:实用工具

指南支持库提供了一个方便的实用工具来实现最终操作这一概念。 由于 C++ 语言不支持 try-finally 构造,因此实现对销毁执行任意操作的自定义清理类型变得很常见。 gsl::finally 实用工具以这种方式实现,并提供一种更统一的方式来跨代码库执行最终操作。

在某些情况下,通过使用 goto 语句(受 C26438 NO_GOTO 阻止)以旧式 C 样式执行最终操作。 很难检测大量使用 goto 的代码中的确切意图,但一些启发式方法有助于找到更好的清理候选项。

备注

  • 此规则是轻量级的,利用标签名称猜测使用最终操作对象的机会。
  • 可引发警告的标签名称包含“end”、“final”、“clean”等单词。
  • 警告显示在 goto 语句中。 有时可能会看到详细输出,但输出可能有助于根据代码的复杂性对代码进行优先级排序。
  • 此规则始终与 C26438 NO_GOTO 配对。 根据优先级,可禁用这些规则之一。

代码分析名称:USE_GSL_FINALLY

示例

使用多个 goto 语句进行清理:

void poll(connection_info info)
{
    connection c = {};
    if (!c.open(info))
        return;

    while (c.wait())
    {
        connection::header h{};
        connection::signature s{};
        if (!c.read_header(h))
            goto end;               // C26448 and C26438
        if (!c.read_signature(s))
            goto end;               // C26448 and C26438
        // ...
    }

end:
    c.close();
}

“使用多个 goto 语句进行清理”已替换为 gsl::finally

void poll(connection_info info)
{
    connection c = {};
    if (!c.open(info))
        return;

    auto end = gsl::finally([&c] { c.close(); });
    while (c.wait())
    {
        connection::header h{};
        connection::signature s{};
        if (!c.read_header(h))
            return;
        if (!c.read_signature(s))
            return;
        // ...
    }
}