gpt4 book ai didi

c - MISRA C 2012 规则 15.4 并用 break 替换 goto

转载 作者:行者123 更新时间:2023-12-03 18:34:03 30 4
gpt4 key购买 nike

关于 MISRA C 2012 规则 15.4 -“用于终止任何迭代语句的 break 或 goto 语句不应超过一个。” - 这个例子正确吗?任何人都可以用一些工具(MISRA 检查器)确认这一点吗?

do {
retval = do_smth();
if (retval != OK) {
break;
}

retval = do_smth2();
if (retval != OK) {
break;
}

retval = do_smth3();
} while (0u);
这只是一个概念,但我在这里尝试的是用 goto 级联替换 break 级联(不幸的是在这种情况下被禁止)。我的观点是 do { } while(0u); 不是迭代语句。
你认为呢?

最佳答案

首先,您的代码确实不遵循规则 15.4,因为您在迭代语句中有 3 个 break1)。但这只是一个建议,只要代码可读且易于遵循,像您一样使用多个中断并没有错。
这些 MISRA 规则的主要原理是防止“复合语句意大利面”,其中复杂的代码从多个嵌套的复合语句中分离出来。在盲目地遵循这些规则之前了解其基本原理很重要。因此,在这种情况下,只需考虑保留代码原样 - 建议规则不需要任何偏差。
否则,有几个选项,如下所示:

MISRA-C 的一个问题是它不允许从一个函数多次返回,即使它使代码更具可读性。否则,显而易见且最易读的解决方案是使用函数:

type do_stuff (void);
{
type retval;

retval = do_smth();
if (retval != OK) { return retval; }

retval = do_smth2();
if (retval != OK) { return retval; }

retval = do_smth3();

return retval;
}
我通常的解决方案是使 MISRA-C 永久偏离多重返回规则,并在使代码更具可读性的情况下允许它,就像在这种情况下一样。
否则,第二个最佳选择可能是旧的“错误转到” - 禁止 goto 的规则在 MISRA-C:2012 中放宽了,所以现在只是建议性的。
  retval = do_smth();
if (retval != OK) { goto error; }

retval = do_smth2();
if (retval != OK) { goto error; }

retval = do_smth3();
if (retval != OK) { goto error; }

goto everything_ok;

error:
/* error handling */

everything_ok:
如果以上两种形式都不行,因为您对 MISRA-C 非常严格,那么第三个选项可能是这样的,我认为它 100% 符合 MISRA-C:
typedef type do_stuff_t (void);

do_stuff_t* const do_stuff[N] = { do_smth, do_smth2, do_smth3 };
type retval = OK;

for(uint32_t i=0u; (i<N) && (retval==OK); i++)
{
retval = do_stuff[i]();
}

My point is that do { } while(0u); is not an iteration statement.


C语言不同意你的看法。
1) 来自 C17:

6.8.5 Iteration statements

Syntax

iteration-statement:
while ( expression ) statement
do statement while ( expression ) ;

关于c - MISRA C 2012 规则 15.4 并用 break 替换 goto,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66369536/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com