strncmp(NULL,"foo",0)是否定义良好?

Mar*_*ian 19 c language-lawyer strncmp

strncmp如果第三个参数为零,将NULL指针作为参数放入是否安全?即调用如:

strncmp(NULL, "foo", 0);
Run Code Online (Sandbox Code Playgroud)

Sou*_*osh 32

这是未定义的行为.

C标准表示通常不应该将无效指针传递给库函数.

引用C11,章节§7.24.1,"字符串函数约定",(强调我的)

声明为的参数size_t n指定函数数组的长度,在n调用该函数时可以为零.除非在本子条款中对特定函数的描述中另有明确说明,否则此类调用上的指针参数仍应具有有效值,7.1.4中所述.在这样的调用中,定位字符的函数不会发生,比较两个字符序列的函数返回零,复制字符的函数复制零个字符.

我在7.24.4.4 strncmp()函数中没有看到任何具体提及(作为上述约束的例外).


要为"无效指针"添加上下文,请引用§7.1.4/ p1,使用库函数

[...]如果函数的参数具有无效值(例如函数域外的值,或程序地址空间外的指针,或空指针,或指向不可修改的指针)当相应参数不是const限定的存储时)或具有可变数量参数的函数不期望的类型(在提升之后),行为是未定义的.[...]

并且NULL,引用§7.19,<stddef.h>

NULL
它扩展为实现定义的空指针常量; [...]

  • 是的,它是(在此上下文中)7.1.4/1"如果函数的参数具有无效值(例如函数域之外的值,或者程序地址空间之外的指针,或者空指针,或当相应参数不是const限定时指向不可修改存储的指针)" (9认同)
  • (很明显,我认为需要添加答案才能完成它) (3认同)
  • @LightnessRacesinOrbit:C89标准是在编译器编写者实现有用行为而不被命令这样做的时代编写的(正如编译器编写者在编写标准之前已经实现了十多年的有用行为这一事实所证明的).该标准的作者希望避免强制执行会阻止符合标准的编译器为平台生成与平台的预先存在的编译器一样高效的代码,这意味着如果替代方案将会产生许多事情UB冒险增加成本...... (3认同)
  • ...*任何*现有的实现,前提是即使99%的实现可以保证行为而不需要额外的成本,使得操作UB不应该阻止它们这样做.不幸的是,实现编写者通常不愿意列出底层平台逻辑比标准所需的所有方式更一致的所有方式,因为这些事情似乎显而易见值得一提.我知道那些重视速度超过语义的编译器编写者已经把它抛到了窗外,但标准版不是为这些人编写的. (2认同)

Lig*_*ica 7

cppreference.com上的C strncmp文档:

当其中一个lhs或是rhs空指针时,行为是未定义的.

只需阅读文档即可.

  • http://cppreference.com不是"文档",它是由爱好者撰写的公共Wiki.鉴于[tag:language-lawyer]标签,我认为我们不应该考虑除语言标准以外的任何内容作为此问题的权威参考. (17认同)
  • @NateEldredge:我没有说它是权威的,也没有说"文档"(它是"cppreference.com上的文档").但做一些基础研究本来是一个好的开始.然后OP可能会要求_confirmation_他们已经看到了什么.输入标准,Sourav的优秀答案.我认为提醒人们阅读文档是有价值的. (3认同)