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。