简体   繁体   English

为什么 glibc printf() 函数与空指针格式不一致?

[英]Why are glibc printf()-functions inconsistent about null pointer formatting?

With glibc,使用 glibc,

  • If your program calls printf("%s", NULL) , you get (null) , but如果你的程序调用printf("%s", NULL) ,你得到(null) ,但是
  • if your program calls printf("%p", NULL) , you get (nil) .如果你的程序调用printf("%p", NULL) ,你得到(nil)

But why is this the case?但为什么会这样呢?

Note: This is not a question about the C language standard , where passing a null pointer for an "%s" specifier results in undefined behavior;注意:这不是关于 C 语言标准的问题,其中为"%s"说明符传递空指针会导致未定义的行为; I'm asking about glibc's choices specifically (and these values are hard-coded in the glibc sources).我特别询问 glibc 的选择(这些值在 glibc 源代码中是硬编码的)。

This is a question for Roland McGrath.这是 Roland McGrath 的问题。

He added vfprintf.c as part of the initial commit of glibc on Feb 17, 1995. This initial version contains both "(nil)" and "(null)" hardcoded for these specific cases.他在 1995 年 2 月 17 日添加了 vfprintf.c 作为 glibc 初始提交的一部分。这个初始版本包含针对这些特定情况硬编码的“(nil)”和“(null)”。 The only comment on this commit is "Initial commit".对此提交的唯一评论是“初始提交”。

https://github.com/lattera/glibc/blob/28f540f45bbacd939bfd07f213bcad2bf730b1bf/stdio/vfprintf.c https://github.com/lattera/glibc/blob/28f540f45bbacd939bfd07f213bcad2bf730b1bf/stdio/vfprintf.c

For more context, the use of "(null)" for strings was present in FreeBSD 4.4 since at least May 27, 1994, although there is no special strings for the %p format specifier:对于更多上下文,至少从 1994 年 5 月 27 日起,FreeBSD 4.4 中就出现了“(null)”作为字符串的使用,尽管%p格式说明符没有特殊的字符串:

https://github.com/freebsd/freebsd-src/commit/58f0484fa251c266ede97b591b499fe3dd4f578e https://github.com/freebsd/freebsd-src/commit/58f0484fa251c266ede97b591b499fe3dd4f578e

C standard. C标准。 7.1.4 7.1.4

¶1 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 value outside the domain of the function, or a pointer outside the address space of the program, or a null pointer, or a pointer to non-modifiable storage when the corresponding parameter is not const-qualified) or a type (after promotion) not expected by a function with variable number of arguments, the behavior is undefined. ¶1 除非在随后的详细说明中另有明确说明,否则以下每一条语句都适用:如果函数的参数具有无效值(例如函数域之外的值,或函数地址空间之外的指针)程序,或空指针,或指向不可修改存储的指针,当相应的参数不是 const 限定的)或类型(提升后)不是具有可变数量参数的函数所期望的,行为是未定义的。

As the C standard does not specify what happens if programmer passes the NULL pointer using %s format specifier, above general rule applies.由于 C 标准没有指定如果程序员使用%s格式说明符传递 NULL 指针会发生什么,上述一般规则适用。

IMO it is Undefined Behaviour and there is no inconsistency. IMO 这是未定义的行为,没有不一致之处。 Any program passing NULL to the print function using %s is invalid.任何使用%s将 NULL 传递给print函数%s都是无效的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM