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 指针的主要内容,如果未能解决你的问题,请参考以下文章