Aquí es una pequeña pieza de código:¿Cómo usar el atributo 'formato' de GCC?
#include <stdio.h>
#include <stdarg.h>
void MyPrintf(char const* format, va_list args);
void MyVariadicPrintf(char const* format, ...);
void MyPrintf(char const* format, va_list args)
{
vprintf(format, args);
}
void MyVariadicPrintf(char const* format, ...)
{
va_list args;
va_start(args, format);
MyPrintf(format, args);
va_end(args);
}
int main(int, char*)
{
MyVariadicPrintf("%s" /* missing 2nd argument */);
return 0;
}
estoy compilación con GCC 4.0, corriendo Xcode en Mac OS X Leopard.
-What y -Wmissing-format-attribute están habilitados.
Este código da una advertencia en la línea 9 (llamado a la vprintf
), lo que sugiere que MyPrintf
podría utilizar el 'formato' atributo:
podría ser posible candidato para el atributo de formato 'printf'
Así que añadir el atributo de esta manera (no estoy seguro si esto es correcto):
void MyPrintf(char const* format, va_list args) __attribute__((format(printf, 1, 0)));
la advertencia anterior desaparece y la misma advertencia aparece ahora en la línea 16 (ca ll a MyPrintf
), lo que sugiere que MyVariadicPrintf
podría usar el atributo 'formato'.
Así que añadir el atributo de esta manera (bastante seguro de que esto es correcto esta vez):
void MyVariadicPrintf(char const* format, ...) __attribute__((format(printf, 1, 2)));
Y ahora tengo la advertencia prevista en la línea 22 (llamada a la MyVariadicPrintf
):
muy pocos argumentos para el formato
- ¿Hice esto bien?
- Observé que en la declaración
MyPrintf
, si eliminé la parte de atributo, igual recibiré la advertencia de búsqueda en la línea 22. También noté que en esta parte de atributo, cambiar el índice de 1 a 2 no dará ninguna advertencia o error ¿Cuál es el correcto y cuál es el objetivo del atributo en esta función? Si agrego la siguiente función
MyVariadicPrintfT
y la llamo (especializada conchar
), obtendré la advertencia sugiriendo usar el atributo 'formato' en esta función. Creo que es imposible porque el argumentoformat
depende del tipo de plantilla. ¿Estoy en lo cierto?template<typename Type> void MyVariadicPrintfT(Type const* format, ...) { va_list args; va_start(args, format); MyPrintf(format, args); va_end(args); }
La última documentación GNU puede encontrar en gnu.org.
Las opciones de advertencia están en section 3.8 (busque "-Wmissing-format-attribute").
Los atributos de función están en section 6.30 (busque el "formato (arquetipo, cadena-índice, primer para verificar)").
Gracias.
En MyVariadicPrintf, entiendo que el compilador verificará el número y los tipos de los argumentos que comienzan en la posición 2 contra la cadena en la posición 1. Pero en el caso de MyPrintf, ¿qué comprueba el compilador? – Guillaume
En el caso de MyPrintf, solo comprobará la validez de la cadena de formato (por ejemplo, que no es algo así como "% _%") – jpalecek
Ok, ¡muchas gracias! – Guillaume