c - 终止带有 else 子句的 if … else if 有什么好处?

标签 c misra safety-critical

我们的组织有一个必需的编码规则(没有任何解释):

if … else if constructs should be terminated with an else clause

示例 1:

if ( x < 0 )
{
   x = 0;
} /* else not needed */

示例 2:

if ( x < 0 )
{
    x = 0;
}
else if ( y < 0 )
{
    x = 3;
}
else    /* this else clause is required, even if the */
{       /* programmer expects this will never be reached */
        /* no change in value of x */
}

这是为了处理什么边缘情况而设计的?

同样让我担心的是,Example 1 不需要 elseExample 2 需要。如果原因是可重用性和可扩展性,我认为在这两种情况下都应该使用 else

最佳答案

正如另一个答案中提到的,这是来自 MISRA-C 编码指南。目的是防御性编程,这是一个经常用于关键任务编程的概念。

也就是说,每个 if - else if 必须以 else 结尾,每个 switch 必须以 default< 结尾.

有两个原因:

  • self 记录代码。如果您写了一个 else 但将其留空,则意味着:“我确实考虑过 ifelse if 都不为真的情况”。

    不写 else 意味着:“要么我考虑了 ifelse if 都不为真的场景,要么我完全忘记了考虑一下,我的代码中可能存在一个严重的错误。

  • 停止失控的代码。在关键任务软件中,您需要编写健壮的程序,以应对极不可能发生的情况。所以你可以看到像

    这样的代码
    if (mybool == TRUE) 
    {
    } 
    else if (mybool == FALSE) 
    {
    }
    else
    {
      // handle error
    }
    

    这段代码对于 PC 程序员和计算机科学家来说是完全陌生的,但它在任务关键型软件中非常有意义,因为它捕捉到“mybool”因任何原因而损坏的情况。

    从历史上看,您会担心 RAM 内存因 EMI/噪音而损坏。今天这不是什么大问题。更有可能的是,代码中其他地方的错误导致内存损坏:指向错误位置的指针、数组越界错误、堆栈溢出、代码失控等。

    所以大多数时候,当你在实现阶段写了错误时,像这样的代码回来打你自己的脸。这意味着它也可以用作调试技术:您正在编写的程序会在您编写错误时告诉您。


编辑

关于为什么在每个if之后都不需要else:

if-elseif-else if-else 完全涵盖了变量可能具有的所有可能值。但是一个普通的 if 语句不一定涵盖所有可能的值,它有更广泛的用途。大多数情况下,您只想检查某个条件,如果不满足,则什么也不做。那么编写防御性编程来覆盖else case 根本就没有意义。

此外,如果您在每个 if 之后都写一个空的 else,它会使代码完全困惑。

MISRA-C:2012 15.7 没有说明为什么不需要 else,它只是说明:

Note: a final else statement is not required for a simple if statement.

关于c - 终止带有 else 子句的 if … else if 有什么好处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55825514/

相关文章:

c - 为什么在 for 循环中使用 fgets 和 sscanf 时会出现段错误?

c - 切换大小写表达式

c++ - 安全编码实践

c - 如何在 MISRAC :2012 that follows Dir 4. 12 和 4.8 中创建模块?

system - 学习安全关键系统开发 (C/C++) 的最佳资源是什么

c - 我应该在 getspent() 之前调用 lckpwdf() 吗?

c - 当没有数据可读取时,Socket read() 会挂起一段时间

c - MISRA 2012 违规 - 类型不匹配(规则 10.1、10.4)

编译输出代码

c - 为什么不将任务上下文置于中断中