在我编写单元测试时,我偶然发现了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
似乎并不常见。
答案 0 :(得分:8)
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); \
对于wprintf,L_("(nil)")
扩展为L"(nil)"
,但稍后几行is_long
设置为0
(即为false)。因此,string
被解释为一个窄字符串,因此打印它将停在其第一个零字节,即(
之后。
报告的错误链接:https://sourceware.org/bugzilla/show_bug.cgi?id=16890 - 这已在glibc 2.20版中修复。
有趣的是,这个漏洞在发现并修复之前已经存在了近15年 - 在报告后的2天内!
答案 1 :(得分:1)
在Ubuntu 14.04 LTS上确认; GNU C库(Ubuntu EGLIBC 2.19-0ubuntu6)。
至少在Debian glibc中似乎是reported bug; 2014年5月1日的错误has been fixed,应该在Glibc 2.20中提供。只需等待上游更新。