2009-06-15 9 views
13

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:

función

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

  1. ¿Hice esto bien?
  2. 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?
  3. Si agrego la siguiente función MyVariadicPrintfT y la llamo (especializada con char), obtendré la advertencia sugiriendo usar el atributo 'formato' en esta función. Creo que es imposible porque el argumento format 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.

Respuesta

10

La documentación tiene la respuesta que necesita.En particular:

  1. el que usted ha publicado es correcto (format(printf, 1, 0)). 1 porque la cadena de formato es el parámetro 1, 0 porque no hay argumentos variados para verificar.
+1

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

+1

En el caso de MyPrintf, solo comprobará la validez de la cadena de formato (por ejemplo, que no es algo así como "% _%") – jpalecek

+0

Ok, ¡muchas gracias! – Guillaume

3

Eche un vistazo a GCC docs on gnu.org. En cuanto a la última pregunta, supongo que MyPrintf no es una función de plantilla y la única definición disponible toma char const* como primer argumento, por lo que se siente seguro al hacer la sugerencia.

Cuestiones relacionadas