在C中,将NULL指针传递给strcmp()时会发生什么?

时间:2014-02-18 20:51:58

标签: c

我已经读过以下结果导致未定义的行为。

strcmp(foo, NULL); 

但究竟发生了什么“在引擎盖下”,可以这么说? foo与垃圾数据进行比较吗? NULL被解除引用了吗?导致“未定义行为”的细节是什么?

4 个答案:

答案 0 :(得分:14)

这取决于实现,可以自由地假设您的参数有效(即在这种情况下不为null)。从执行到执行,或者从一个实现/平台到另一个实现/平台,行为可能会也可能不会重现。

答案 1 :(得分:8)

C11在7.1.4“使用库函数”中非常清楚:

  

除非在详细说明中另有明确说明,否则以下每个陈述均适用   以下描述:如果函数的参数具有无效值(例如[...]空指针[...])[...],则行为未定义。

7.24.4中strcmp的描述没有另外说明,因此行为确实未定义。

答案 2 :(得分:5)

这是glibc中strcmp的当前实现:

/* Compare S1 and S2, returning less than, equal to or
   greater than zero if S1 is lexicographically less than,
   equal to or greater than S2.  */
int
strcmp (p1, p2)
     const char *p1;
     const char *p2;
{
  const unsigned char *s1 = (const unsigned char *) p1;
  const unsigned char *s2 = (const unsigned char *) p2;
  unsigned char c1, c2;

  do
    {
      c1 = (unsigned char) *s1++;
      c2 = (unsigned char) *s2++;
      if (c1 == '\0')
    return c1 - c2;
    }
  while (c1 == c2);

  return c1 - c2;
}

答案 3 :(得分:0)

你传递了两个指针,strcmp取消引用它们的内容并进行比较,直到遇到差异或空字符。失败发生在不同的抽象级别,strcmp本身就没有失败。许多系统在解除引用NULL指针时生成SIGSEGV符号,但这不是必需的。

请注意,ISO标准没有定义很多内容,因此将实现细节留给实现。在ISO C级别,您的示例没有任何问题,但结果不能保证是可预测的。 (除非你参考基础系统的规则,否则没有任何实际测试可以保证精确和可重复,除非他们另有说明。)

当我们谈论抽象级别时,我们不能问“如果”,因为规则很明确并且说“不要这样做,行为没有在这里定义”。