[英]In C, what exactly happens when you pass a NULL pointer to strcmp()?
I have read that the following results in undefined behavior. 我已经读过以下结果导致未定义的行为。
strcmp(foo, NULL);
But what exactly happens "underneath the hood," so to speak? 但究竟发生了什么“在引擎盖下”,可以这么说呢? Is
foo
compared to garbage data? foo
与垃圾数据相比? Is NULL
dereferenced? 是否取消引用
NULL
? What are the details that cause "undefined behavior"? 导致“未定义行为”的细节是什么?
It depends on the implementation, which is free to assume your parameters are valid (ie not null in this case). 这取决于实现,可以自由地假设您的参数有效(在这种情况下不为null)。 The behaviour may or may not be reproducible from execution to execution, or from one implementation/platform to another.
该行为可以或可以不是从执行到执行,或从一个实现/平台到另一个实现/平台可再现。
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 strcmp
in 7.24.4 does not state otherwise, so the behaviour is indeed undefined. 7.24.4中对
strcmp
的描述没有另外说明,因此行为确实未定义。
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 == '\0')
return c1 - c2;
}
while (c1 == c2);
return c1 - c2;
}
You pass two pointers, and strcmp dereferences their contents and compares until it meets the difference or null character. 你传递两个指针,strcmp取消引用它们的内容并进行比较,直到它遇到差异或空字符。 Fail happens at different abstraction level, strcmp is fail-free on it's own.
失败发生在不同的抽象级别,strcmp本身就没有失败。 Many systems generate SIGSEGV signsl on dereferencing NULL pointer, but this is not the requirement.
许多系统在取消引用NULL指针时生成SIGSEGV标志,但这不是必需的。
Please note that ISO standards do not define many things, leaving implementation details up to implementations. 请注意,ISO标准没有定义很多东西,将实现细节留给实现。 At ISO C level there is nothing wrong with your example, but the results are not guaranteed to be predictable.
在ISO C级别,您的示例没有任何问题,但结果不能保证是可预测的。 (And no practical test is guaranteed to be precise and reproducible, unless you consult the rules of underlying system and they say otherwise).
(并且除非您查阅基础系统的规则并且他们另有说明,否则不保证实际测试的准确性和可重复性。
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". 当我们谈论抽象层次时,我们不能问“如果”,因为规则是明确的并且说“不要这样做,行为没有在这里定义”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.