☰
  • 首页
  • 规则分类
  • 项目介绍
search
•••

禁用 goto 语句

9.7.3 ID_forbidGoto
目录 › next › previous

历史表明,goto 语句会破坏程序的结构性规划,很容易导致逻辑混乱且不利于阅读和维护,在非自动生成的、对可读性有要求的代码中,建议禁用 goto 语句。

示例:

if (cond0) {
    goto L;    // Non-compliant
}
....
if (cond1) {
L:
    ....
}

语句的排列和作用域的嵌套描述了程序的静态结构,清晰的静态结构使人易于理解程序的行为,而 goto 语句会打破这种结构,无规律的跳转会严重地降低代码可读性,例中 goto L 会绕过第二个 if 语句的条件约束,可读性很差,应被禁止。

C 语言的流程管理较为简单,goto 语句可提供一定的灵活性,但不应作为常规实现手段,也应受一定的限制,在 C 代码中使用 goto 语句应遵循 ID_forbidGotoBlocks 和 ID_forbidGotoBack 等规则。

C++ 语言提供了更丰富的流程管理功能,在 C++ 代码中不应再使用 goto 语句。

下面给出 goto 语句的一种常用模式:

void foo(size_t n)
{
    int *a = NULL, *b = NULL, *c = NULL;
    a = (int*)malloc(n);
    if (!a) {
        goto E;
    }
    b = (int*)malloc(n);
    if (!b) {
        goto E;
    }
    c = (int*)malloc(n);    // Multiple resource allocation
    if (!c) {
        goto E;
    }
    ....
E:                          // Single exit point
    free(a);
    free(b);
    free(c);
}

在多次资源分配过程中,如果某次分配失败则需要释放已分配的资源,利用 goto 语句可实现资源的统一释放,在 C 代码中如果不用 goto 语句反而会很繁琐,所以这种模式在 C 代码中可以复用。

由于 C++ 提供容器、智能指针等更丰富的资源管理手段,所以不建议在 C++ 代码中再使用这种模式,即使标准库没有和相关资源对应的功能,也应该利用“RAII”等机制对其先封装再使用。

void foo(size_t n) {
    std::vector<int> a, b, c;   // Safe and brief
    ....
}

相关

ID_forbidGotoBlocks ID_forbidGotoBack

参考

C++ Core Guidelines ES.76 MISRA C 2012 15.1
Copyright©2024 360 Security Technology Inc., Licensed under the Apache-2.0 license.