双方都有副作用吗?

Aka*_*kay 3 c lint side-effects misra pc-lint

我使用以下C代码对MISRA 2004和MISRA 2012运行静态代码分析:

BOOL_TYPE Strings_Are_Equal(const char *s1, const char *s2)
{
  BOOL_TYPE result = True;
  const char *str1 = s1;
  const char *str2 = s2;

  if (NULL == s1 || NULL == s2)
  {
    result = False;
  }
  else if (strlen(s1) != strlen(s2))
  {
    result = False;
  }
  else
  {
    while (*str1 != 0)
    {
      if(tolower(*str1++) != tolower(*str2++))
      {
        result = False;
        break;
      }
    }
  }

  return result;
}
Run Code Online (Sandbox Code Playgroud)

并从PC-lint报告中得到以下结论: 在此输入图像描述

有人可以解释第58和66行的代码如何遭受副作用,我该如何纠正?

Lun*_*din 7

在使用C标准的正式定义时,调用函数可以调用副作用.

在具体情况下strlen(s1) != strlen(s2),这些功能中没有任何内容可能造成伤害.用例如内部static变量实现它们是没有意义的.但是如果存在这样的内部变量,则评估顺序可以根据首先执行的函数调用给出不同的结果.这可能是警告背后的基本原理.

如果tolower(*str1++) != tolower(*str2++)有两个函数调用副作用和两个来自++运算符的变量赋值副作用,则单个表达式中总共有4个.尽管这种特殊情况是安全的,但这样的代码是危险的,因为它可能取决于评估的顺序,甚至完全没有序列(如i=i++;),这将是一个严重的错误.

通过将函数结果存储在临时变量中来解决此问题.永远不要++与其他运营商混在一起,因为这既危险又毫无意义,并被另一个MISRA规则禁止:

MISRA-C:2004规则12.13

增量(++)和减量( - )运算符不应与表达式中的其他运算符混合使用.