MISRA 2012规则14.2

时间:2018-06-05 03:34:41

标签: 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>
         */       
    }
}

此处为for (i=0; i< foo(&a) ; 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 */
    }

2 个答案:

答案 0 :(得分:5)

您的示例代码违反了引用的规则(第一个子弹),因为
它确实有副作用(或者编译器无法真正说明,因为调用带有原型的函数会产生这样的副作用 - 并且碰巧至少有一个)。

如果您的示例可能违反了引用的规则(第三个项目符号) 循环连续条件(i< foo(&a))的(侧面)效应(通过您的特定MISRA分析仪)计算为&#34;循环体&#34;的一部分。 (我不会,但你的工具可能。)

因此,您显示的代码违反了规则一到两次。

答案 1 :(得分:0)

规则14.2的基本原理表明,该规则旨在限制for循环,停止&#34;聪明&#34;使用,从而使代码更容易审查和分析......

我有一个简单的格言:

  • 如果您有预先确定的迭代次数,请使用for循环
  • 如果您没有预先确定的迭代次数,请使用while ... do循环

假设foo(&a)不返回常量,那么最好使用while ... do循环:

int a = 20;
int i = 0;

while ( i < foo(&a) )
{
  // Loop body
  ...
  ++i;
}

注意:请参阅免责声明。