我有一个非常简单的函数,它创建了一个时间延迟:
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 的规则:
静态分析工具似乎期待一个常见的情况,例如:
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
声明可能会有所帮助。
虽然你可能对getTime()
有一些了解,但静态分析器基本上假设getTime()
的返回值可能永远不会触发循环结束条件,因此循环可能是无限的。
因此,您需要的是一个被分析仪接受的无限循环,并结合回路体内的中断条件。据我从快速搜索中可以看出,只有for(;;)
被MISRA接受为无限循环。
for ( ; ; )
{
if (t <= get_time()) break;
}
这不应触发警告。
每个编译器或代码审查工具或内存泄漏分析器工具都有自己的逻辑,并根据其逻辑为您提供警告或错误消息。在这种情况下,编译器/工具正在考虑t
作为控制变量,基于哪个while loop
应该中断。由于编译器/工具在 while 循环块中找不到任何代码来操作变量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
视为控制变量,也不应引发任何警告。