wprintf:%p com o ponteiro NULL
Pergunta
Como eu estava escrevendo um teste de unidade, me deparei com algumas comportamento estranho de glibc
, sobre "%p"
e o NULL
ponteiro.
Se eu tiver uma linha como printf("NULL pointer is %p\n", NULL);
, então eu vejo NULL pointer is (nil)
impresso para a tela, como eu esperava.
Se eu, em vez de utilizar a versão de todo o carácter: wprintf(L"NULL pointer is %p\n", NULL);
, em seguida, imprime NULL pointer is (
, e pára na parêntese de abertura.Se eu imprimir um nãoNULL
ponteiro, ele imprime esse ponteiro, normal e largo versões de caracteres.Isso é um bug conhecido do glibc
, ou será que eu estou faltando alguma coisa?
NB:Eu percebo que o padrão de C diz que os ponteiros com %p
são convertidos em uma implementação definido pelo modo;ele só parece incomum para imprimir (
para um NULL
ponteiro.
Solução
Este é definitivamente um erro: 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); \
O L_("(nil)")
expande-se para L"(nil)"
para wprintf, mas um par de linhas mais tarde is_long
é definido como 0
(i.é.false).Como resultado string
é interpretado como um estreito-cadeia de caracteres, para que a impressão que vai parar no seu primeiro byte zero i.e.após o (
.
Bug reportado link: https://sourceware.org/bugzilla/show_bug.cgi?id=16890 - isso é corrigido na versão 2.20 da glibc.
Curiosamente, este erro parece ter existido por quase 15 anos antes de ele foi encontrado e fixo prazo de 2 dias após o seu relato!
Outras dicas
Confirmado no Ubuntu 14.04 LTS;Biblioteca GNU C (Ubuntu ALLEGRO 2.19-0ubuntu6).
Parece ser um bug reportado em pelo menos Debian glibc;o bug foi corrigido em 1 de Maio de 2014, e deve estar disponível na Glibc 2.20.É só esperar para montante atualizações.