C MISRA 2012第14.2条规则

C MISRA 2012第14.2条规则,c,static-analysis,misra,C,Static Analysis,Misra,我有一个与MISRA 2012规则14.2“for循环应格式良好”相关的问题 考虑以下示例代码: int foo (int *ptr) { (*ptr)--; return *ptr; } void main() { int a =20; int i; for (i=0; i< foo(&a) ; i++) { /* <loop body> */

我有一个与MISRA 2012规则14.2“for循环应格式良好”相关的问题

考虑以下示例代码:

int foo (int *ptr)
{
    (*ptr)--;
     return *ptr;
}

void main()
{
    int a =20;
    int i;
    for (i=0; i< foo(&a) ; i++)
    {
         /*
         <loop body>
         */       
    }
}
intfoo(int*ptr)
{
(*ptr)--;
返回*ptr;
}
void main()
{
INTA=20;
int i;
对于(i=0;i
这里是(i=0;i的第
行,我得到了一个MISRA违规,14.2。
问题是当我们在如下所示的函数中修改循环条件(i
这只是一个示例,对于14.2,请不要在上面的示例代码中关注循环是无限的


14.2规则: 第二个从句,其中
-应为无持续副作用的表达,且
-应使用循环计数器和可选的循环控制标志,以及
-不得使用在for循环体中修改的任何其他对象。

示例:-

 bool_t flag = false;
    for ( int16_t i = 0; ( i < 5 ) && !flag; i++ )
    {
    if ( C )
    {
    flag = true; /* Compliant - allows early termination
    * of loop */
    }
    i = i + 3; /* Non-compliant - altering the loop
    * counter */
    }
bool\u t标志=false;
对于(int16_t i=0;(i<5)和&!flag;i++)
{
如果(C)
{
flag=true;/*兼容-允许提前终止
*环的*/
}
i=i+3;/*不合规-改变回路
*柜台*/
}


您的示例代码违反了引用的规则(第一个项目符号),因为
它确实有副作用(或者编译器无法真正判断,因为使用原型调用函数会允许这种副作用,而且碰巧至少有一个副作用)

您的示例可能违反引用的规则(第三个项目符号),如果 循环持续条件(
i
)的(副作用)作为“循环体”的一部分进行计算(由特定的MISRA分析仪)。(我不会,但你的工具可能会。)


因此,您显示的代码违反规则的次数介于一次和两次之间。

规则14.2的基本原理表明,该规则旨在限制
循环,停止“聪明”使用,从而使代码更易于查看和分析

我有一句简单的格言:

  • 如果有预先确定的迭代次数,请使用
    for
    循环
  • 如果没有预先确定的迭代次数,请在。。。执行循环
假设
foo(&a)
is不返回常量,您最好在。。。执行循环:

int a = 20;
int i = 0;

while ( i < foo(&a) )
{
  // Loop body
  ...
  ++i;
}
inta=20;
int i=0;
while(i

注意:有关免责声明,请参阅配置文件。

您是说显示的代码不是无限循环吗?您必须初始化
a
,以确保安全。但这要么是一个无限循环,要么一次也不会循环。@Yunnosch:谢谢你的评论,sameYou对第二条评论的反应是,第一条评论没有说服你。我想说的是,你应该改进你的观点,以帮助人们关注实际问题。所显示的代码将产生我已经演示过的那种澄清问题注释。对于一个不太分散注意力的MCVE(我希望保留其示例功能),我建议init
a=20
并将函数体更改为
(*ptr)--;返回*ptr