我可以将空指针传递给memcmp吗?

时间:2013-05-03 15:50:21

标签: c++ c memcmp

特别是,以下定义明确,还是表现出未定义的行为?

memcmp(0, 0, 0);

这在C和C ++之间有区别吗?理想情况下,请提供标准报价。

2 个答案:

答案 0 :(得分:31)

  

特别是,以下定义明确,还是表现出未定义的行为?

未定义。 C99 7.21.1 / 2说明了所有字符串函数:

  

除非明确说明   否则在本子条款中的特定函数的描述中,指针参数   在这样的电话上仍然应该有有效值

并且7.21.4.1中memcmp的描述没有明确说明。

  

这在C和C ++之间有区别吗?

不,C ++对C库函数的定义遵循C语言,对memcmp没有什么特别的说法。

答案 1 :(得分:3)

令人惊讶的是,尽管这似乎是标准中一个明显错误的情况-忽略了零长度memcmp很好(并且始终返回0)的原因-大量的理论用来解释为什么这样做被标记为“未定义的行为”。上面接受的答案是一个很好的例子,以后的讨论here也是如此。

不幸的是,在memcmp(0,0,0)未定义的理论得到支持之后,Gcc决定通过在memcmp中添加__nonull属性来强烈执行这一不幸的决定,从而导致可能错误的优化和UBSAN警告。只有到那时,这个调用才真正变得未定义:-(

但是,如果我们从逻辑上看,memcmp(0, 0, 0)是定义明确的,并且应始终返回0(等于):Posixmemcmp()的功能描述为:

memcmp()函数应将s1指向的对象的前n个字节(每个解释为无符号字符)与s2指向的对象的前n个字节进行比较。

当n = 0时,这意味着将不比较任何字节。如果不比较任何字节,则不应取消引用任何指针,并且该指针是什么都没有关系。这应该很明显,而且C标准忘了提及它的事实不过是标准中的一个错误。

有趣的是,Linux memcmp(3)FreeBSD memcmp(3)手册页与gcc意见不一致,并宣称应允许这种情况:

Linux手册页显示:

如果n为零,则返回值为零。

BSD会说:

零长字符串始终相同。