PORTING.VAR.EFFECTS
变量在一个表达式中使用了两次,且其中一次会产生副作用
PORTING 检查器会标识那些可能依赖于不同编译器中特定实施细则的代码。PORTING.VAR.EFFECTS 检查器会检测一个变量在表达式中使用了两次,并且其中至少一次会产生副作用的情况。
该检查器会检测对 MISRA C 2004 标准的规则 12.2 以及 MISRA C++ 2008 标准的规则 5-0-1 的违规情况。
漏洞与风险
C 标准并未定义计算的顺序,因此当在不同编译器之间移植代码时,使用语法快捷方式可能具有明显的操作影响。该检查器会检测将分配作为函数调用的参数列表的一部分的情况。无法保证这种分配始终发生在函数调用之前,因此会在不同平台上导致不同的结果。
缓解与预防
请勿使用语法快捷方式,尤其是当可能将代码移植到其他编译器时。
漏洞代码示例
复制
void foo(int m) { printf("Foo called with %d\n", m); }
void bar(int m) { printf("Bar called with %d\b", m); }
void laab()
{
int m = 0;
void (*fp[3])(int);
fp[0] = foo;
fp[1] = bar;
(*fp[++m])(++m); // PORTING.VAR.EFFECTS
}
取决于所使用的编译器,可能调用函数 foo 或 bar,虽然 m 的值可能始终是 2。
修正代码示例
复制
void foo(int m) { printf("Foo called with %d\n", m); }
void bar(int m) { pritnf("Bar called with %d\b", m); }
void laab(int fn)
{
int m = 0;
void (*fp[3])(int);
fp[0] = foo;
fp[1] = bar;
(*fp[fn])(++m);
}
在经修复的代码中,表达式不再有歧义。我们准确地知道将调用哪个函数,而 m 也将如预期一样始终为 1。