wprintf: %p 带 NULL 指针

Posted

技术标签:

【中文标题】wprintf: %p 带 NULL 指针【英文标题】:wprintf: %p with NULL pointer 【发布时间】:2014-09-20 01:11:56 【问题描述】:

在编写单元测试时,我偶然发现了来自glibc 的一些奇怪行为,涉及"%p"NULL 指针。

如果我有一行如printf("NULL pointer is %p\n", NULL);,那么我会看到NULL pointer is (nil) 打印到屏幕上,正如我所料。

如果我改用宽字符版本:wprintf(L"NULL pointer is %p\n", NULL);,那么它会打印出NULL pointer is (,并在左括号处停止。如果我打印一个非NULL 指针,它会打印该指针,包括普通和宽字符版本。这是glibc 的已知错误,还是我只是遗漏了什么?

注意:我意识到 C 标准说带有 %p 的指针以实现定义的方式进行转换;只为 NULL 指针打印 ( 似乎很不寻常。

【问题讨论】:

看起来像一个错误..... 结果字符串与格式字符串的期望不匹配:在格式字符串中,%p 周围有单引号 ('),但它们没有出现在结果字符串。这是问题中的错字吗? 你试过NULL而不是L'\0'吗? @FiddlingBits %p 需要一个指针,而 L'\0' 是一个整数常量。无论如何,它仍然给出相同的结果。 This can't be right either... 【参考方案1】:

这绝对是一个错误:https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=blob;f=stdio-common/vfprintf.c;hb=c15cf13a8a672bd27bf3d94b995c52872eed537d#l932

 934             /* Write "(nil)" for a nil pointer.  */                           \
 935             string = (CHAR_T *) L_("(nil)");                                  \
 936             /* Make sure the full string "(nil)" is printed.  */              \
 937             if (prec < 5)                                                     \
 938               prec = 5;                                                       \
 939             is_long = 0;        /* This is no wide-char string.  */           \
 940             goto LABEL (print_string);                                        \

L_("(nil)") 扩展为 wprintf 的 L"(nil)",但几行之后 is_long 设置为 0(即 false)。因此,string 被解释为窄字符串,因此打印将在其第一个零字节处停止,即在 ( 之后。

报告的错误链接:https://sourceware.org/bugzilla/show_bug.cgi?id=16890 - 这已在 glibc 2.20 版中修复。

有趣的是,这个错误似乎已经存在了将近 15 年才被发现并修复 - 在报告后的 2 天内!

【讨论】:

【参考方案2】:

在 Ubuntu 14.04 LTS 上确认; GNU C 库 (Ubuntu EGLIBC 2.19-0ubuntu6)。

至少在 Debian glibc 中似乎是 reported bug; 2014 年 5 月 1 日的错误 has been fixed,应该在 Glibc 2.20 中可用。等待上游更新。

【讨论】:

以上是关于wprintf: %p 带 NULL 指针的主要内容,如果未能解决你的问题,请参考以下文章

指针 分配空间

为什么delete指针后指针设为null

const与指针引用

delete指针以后应赋值为NULL

带分号与不带分号的while循环内的指针递减[关闭]

c语言如何给指针参数赋值为null?