MISRA 2012 规则 14.2
MISRA 2012 Rule 14.2
我有一个与 MISRA 2012 规则 14.2 有关的问题 "A for loop shall be well-formed"
考虑以下示例代码:
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< foo(&a)) 中存在的变量 (a) 时。这是有效的违规行为吗?
这只是一个示例,对于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 */
}
您的示例代码违反了引用的规则(第一个项目符号),因为
它确实有副作用(或者编译器无法真正分辨出来,因为调用带有允许此类副作用的原型的函数 - 并且碰巧至少有一个)。
您的示例可能违反引用的规则(第三个项目符号)如果
循环继续条件 (i< foo(&a)
) 的(副作用)被计算(由您的特定 MISRA 分析器)作为 "the loop body" 的一部分。 (我不会,但你的工具可能会。)
因此您显示的代码违反了规则一到两次。
规则 14.2 的基本原理表明该规则旨在限制 for
循环,停止 "clever" 使用,从而使代码更易于审查和分析...
我有一个简单的格言:
- 如果您有预先确定的迭代次数,请使用
for
循环
- 如果您没有可预先确定的迭代次数,请使用
while ... do
循环
假设 foo(&a)
不是 return 常数,你最好使用 while ... do
循环:
int a = 20;
int i = 0;
while ( i < foo(&a) )
{
// Loop body
...
++i;
}
注意:请参阅个人资料了解免责声明。
我有一个与 MISRA 2012 规则 14.2 有关的问题 "A for loop shall be well-formed"
考虑以下示例代码:
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< foo(&a)) 中存在的变量 (a) 时。这是有效的违规行为吗?
这只是一个示例,对于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 */
}
您的示例代码违反了引用的规则(第一个项目符号),因为
它确实有副作用(或者编译器无法真正分辨出来,因为调用带有允许此类副作用的原型的函数 - 并且碰巧至少有一个)。
您的示例可能违反引用的规则(第三个项目符号)如果
循环继续条件 (i< foo(&a)
) 的(副作用)被计算(由您的特定 MISRA 分析器)作为 "the loop body" 的一部分。 (我不会,但你的工具可能会。)
因此您显示的代码违反了规则一到两次。
规则 14.2 的基本原理表明该规则旨在限制 for
循环,停止 "clever" 使用,从而使代码更易于审查和分析...
我有一个简单的格言:
- 如果您有预先确定的迭代次数,请使用
for
循环 - 如果您没有可预先确定的迭代次数,请使用
while ... do
循环
假设 foo(&a)
不是 return 常数,你最好使用 while ... do
循环:
int a = 20;
int i = 0;
while ( i < foo(&a) )
{
// Loop body
...
++i;
}
注意:请参阅个人资料了解免责声明。