绕过警告:“控制变量未在循环内修改”

时间:2018-01-03 15:13:16

标签: c while-loop misra

我有一个非常简单的功能,它创造了一个时间延迟:

void delay(int time_in_ms)
{
   int t = get_time() + time_in_ms;
   while (get_time() < t)
   {
   };
}

delay(750);

我收到警告,控制变量t未在while循环内修改。我不需要修改变量,只要条件满足,我只需要在while循环中。如何以“好”的方式绕过这个?

警告由MISRA静态分析工具创建。完整的信息:

  

“此循环结构中的控制变量永远不会被修改”   MISRA C:2012适用于第2467条的规则:

3 个答案:

答案 0 :(得分:2)

静态分析工具似乎期待一个常见的情况,如:

int i = 0;
while(i < get_size(var))
{
    do_something(var[i]);
    i++;
}

但是,在您的情况下,循环控制变量是getTime()的结果,而t是限制。

您可以使用真正的循环控制变量。编译器可能会优化它。

void delay(int time_in_ms)
{
   int t = get_time() + time_in_ms;
   int current_time;
   do
   {
      current_time = getTime();
   } while(current_time < t);
}

或者您可以尝试发现是什么让您的静态分析工具认为t是循环控制变量。 const int t声明可以提供帮助。

答案 1 :(得分:0)

每个编译器或代码审查工具或内存泄漏分析器工具都有自己的逻辑,并根据它的逻辑给出警告或错误消息。在这种情况下,您的编译器/工具正在考虑t作为控件变量,基于while loop应该中断。由于编译器/工具在循环块中没有找到任何代码来操作变量t,因此它向您发出警告,因为它认为您的while loop可能是无限while loop。您可以忽略它,因为您确定它永远不会是无限循环,或者您可以以不同的方式修改代码(请参阅下文,但可能无法修复此警告)以避免此警告。

void delay(int time_in_ms)
{
   int t = get_time() + time_in_ms;
   while ( t > get_time() );
}

delay(750);      

在上述更改中,我将t移至左侧,以便您的工具不应将t视为控制变量,并且不应发出任何警告。

答案 2 :(得分:0)

虽然您可能对getTime()有一些了解,但静态分析器基本上假设getTime()的返回值可能永远不会触发循环结束条件,因此循环可能是无限的。

所以你需要的是分析器接受的无限循环,以及循环体内的中断条件。据我所知,通过快速搜索,只有for(;;)被MISRA视为无限循环。

for ( ; ; )
{
    if (t <= get_time()) break;
}

这不应该触发警告。