wprintf:%p с нулевым указателем
Вопрос
Когда я писал модульный тест, я наткнулся на некоторое странное поведение 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
указатель.
Решение
Это определенно ошибка: 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)")
расширяется до L"(nil)"
для wprintf, но парой строк позже is_long
установлено значение 0
(т.е.ложь).В результате string
интерпретируется как строка из узких символов, поэтому ее печать остановится на первом нулевом байте, т.е.после того, как (
.
Ссылка на сообщение об ошибке: https://sourceware.org/bugzilla/show_bug.cgi?id=16890 - это исправлено в версии 2.20 glibc.
Интересно, что эта ошибка, похоже, существовала почти 15 лет, прежде чем ее обнаружили и исправили - в течение 2 дней с момента сообщения о ней!
Другие советы
Подтверждено в Ubuntu 14.04 LTS;Библиотека GNU C (Ubuntu EGLIBC 2.19-0ubuntu6).
Кажется, это сообщил об ошибке по крайней мере, в Debian glibc;баг было исправлено 1 мая 2014 г. и должен быть доступен в Glibc 2.20.Просто дождитесь обновлений апстрима.