【问题标题】:MISRA 2012 Rule 14.2MISRA 2012 规则 14.2
【发布时间】:2018-06-05 03:34:40
【问题描述】:

我有一个与 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&lt; foo(&amp;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 */
    }

【问题讨论】:

  • 你是说显示的代码不是无限循环吗?您必须初始化 a 才能确定。但它要么是一个无限循环,要么永远不会循环一次。
  • @Yunnosch : 谢谢你的评论,同样的注释
  • 你对第二条评论的反应,第一条没有说服你?
  • 我想说的是,您应该改进您的minimal reproducible example,以帮助人们专注于实际问题。显示的代码会引起我演示过的那种澄清问题。
  • 对于一个不那么分散注意力的 MCVE(我希望保留它的示例函数)我建议初始化 a=20; 并将函数体更改为 (*ptr)--; return *ptr;

标签: c static-analysis misra


【解决方案1】:

您的示例代码违反了引用规则(第一个项目符号),因为
它确实有副作用(或者编译器无法真正分辨,因为调用带有原型的函数会允许这种副作用 - 并且恰好有至少一个)。

如果您的示例可能违反引用的规则(第三个项目符号) 循环继续条件 (i&lt; foo(&amp;a)) 的(副作用)效应(由您的特定 MISRA 分析器)计为“循环体”的一部分。 (我不会,但你的工具可能会。)

所以你显示的代码违反了规则一到两次。

【讨论】:

    【解决方案2】:

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

    我有一个简单的格言:

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

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

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

    注意:请参阅个人资料以获取免责声明。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多