C语言 在 C 中,当您将 NULL 指针传递给 strcmp() 时究竟会发生什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21865041/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 10:47:13  来源:igfitidea点击:

In C, what exactly happens when you pass a NULL pointer to strcmp()?

c

提问by jfmercer

I have read that the following results in undefined behavior.

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

strcmp(foo, NULL); 

But what exactly happens "underneath the hood," so to speak? Is foocompared to garbage data? Is NULLdereferenced? What are the details that cause "undefined behavior"?

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

回答by justin

It depends on the implementation, which is free to assume your parameters are valid (i.e. not null in this case). The behaviour may or may not be reproducible from execution to execution, or from one implementation/platform to another.

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

回答by Kerrek SB

C11 makes this very clear in 7.1.4, "Use of library functions":

C11 在 7.1.4,“库函数的使用”中非常清楚地说明了这一点:

Each of the following statements applies unless explicitly stated otherwise in the detailed descriptions that follow: If an argument to a function has an invalid value (such as [...] a null pointer [...]) [...], the behavior is undefined.

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

The description of strcmpin 7.24.4 does not state otherwise, so the behaviour is indeed undefined.

strcmp7.24.4 中的描述没有另外说明,因此行为确实是未定义的。

回答by kobrien

This is the current implementation of strcmp in glibc:

这是当前在 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 == '##代码##')
    return c1 - c2;
    }
  while (c1 == c2);

  return c1 - c2;
}

回答by user3125367

You pass two pointers, and strcmp dereferences their contents and compares until it meets the difference or null character. Fail happens at different abstraction level, strcmp is fail-free on it's own. Many systems generate SIGSEGV signsl on dereferencing NULL pointer, but this is not the requirement.

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

Please note that ISO standards do not define many things, leaving implementation details up to implementations. At ISO C level there is nothing wrong with your example, but the results are not guaranteed to be predictable. (And no practical test is guaranteed to be precise and reproducible, unless you consult the rules of underlying system and they say otherwise).

请注意,ISO 标准没有定义很多东西,将实现细节留给实现。在 ISO C 级别,您的示例没有任何问题,但不能保证结果是可预测的。(并且不保证任何实际测试都是精确和可重复的,除非您查阅底层系统的规则并且他们另有说明)。

When we are talking about abstraction levels, we cannot ask "what if", because the rules are clear and say "do not do that, behavior is not defined here".

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