Sí, se requiere el molde a void*
.
int a;
printf("address of a = %p\n", &a);
&a
es de tipo int*
; El formato "%p"
de printf requiere un argumento del tipo void*
. El argumento int*
es no convertido implícitamente a void*
, porque la declaración de printf
no proporciona información de tipo para otros parámetros que no sean el primero (la cadena de formato). Todos los argumentos posteriores a la cadena de formato tienen aplicadas las promociones de argumento por defecto; estas promociones no convierten int*
en void*
.
El resultado probable es que printf
ve un argumento que es realmente del tipo int*
y lo interpreta como si se tratara de tipo void*
. Esto es tipo-juego de palabras, no conversión, y tiene un comportamiento indefinido. Es probable que funcione si int*
y void*
tienen la misma representación, pero el estándar de idioma no garantiza eso, ni siquiera por implicación. Y el tipo de juego de palabras que describí es solo un comportamiento posible; el estándar dice literalmente nada sobre lo que puede suceder.
(Si lo hace lo mismo con una función no variadic con un prototipo visible, por lo que el compilador sabe en el momento de la llamada que el parámetro es de tipo void*
, entonces se va a generar código para hacer una implícita int*
-to- void*
conversión. Ese no es el caso aquí.)
por qué debería dar una advertencia cuando está dando un parámetro a printf que acepta cualquier cosa y recupera los datos especificados por% p, que es la dirección que apunta a un . – TigOldBitties
'printf' no es seguro de tipos - ¿por qué deberían sus variables dar una sacudida de jammy? Depende de usted. Welcomen a OOP. –
@TigOldBitties: Porque gcc realiza análisis estáticos basados en cadenas de formato 'printf'. –