2012-07-23 11 views
14

estoy tratando de definir un método de clase para las impresiones de depuración que se comportará como printf:¿Cómo debo usar correctamente __attribute__ ((format (printf, x, y))) dentro de un método de clase en C++?

inline void debug(const char* fmt, ...) __attribute__ ((format (printf, 1, 2))) 

Esta queja:

error: format string argument not a string type 

me recordó que una declaración de método de clase tiene un parámetro implícito this , así que cambié las ubicaciones de los parámetros a 2, 3:

inline void debug(const char* fmt, ...) __attribute__ ((format (printf, 2, 3))) 

y ahora se compila, pero parece que los parámetros están desplazados, como si el parámetro this estuviera siendo tratado como parte de la lista de argumentos.

¿Cómo puedo saber la función que this no es parte de la cadena que quiero imprimir?

+0

¿Se puede utilizar plantillas variadic? Si es así, puede hacer un [tipo impresión segura] (http://www.generic-programming.org/~dgregor/cpp/variadic-templates.html) – chris

+1

No piense demasiado acerca de 'esto'. No es un argumento explícito, punto. Simplemente siga el manual de GCC, que dice que para las funciones de miembro debe agregar 1 a los argumentos de atributo 'format'. Es solo una regla opaca, dada por el proveedor de una extensión de compilación. –

+2

printf (2, 3) es correcto. Definir "parece desplazado" ...? –

Respuesta

15

Lo has hecho. this es el argumento 1, por lo que al decir format(printf, 2, 3) usted está diciendo al compilador que no se está imprimiendo this, que está imprimiendo el argumento 2 (fmt) con argumentos adicionales allá de eso.

+0

Tiene sentido pero me pregunto por qué esto no se documenta en cualquier lugar – dashesy

+1

@dashesy: ​​se documenta en la página de información de gcc para el atributo 'format' ... –

+1

tienes razón [aquí] (https: //gcc.gnu. org/onlinedocs/gcc/Common-Function-Attributes.html # Common-Function-Attributes): ** Dado que los métodos C++ no estáticos tienen un argumento implícito, los argumentos de dichos métodos deben contarse desde dos, no uno, al proporcionar valores para string-index y first-to-check . ** – dashesy

2

Ya que sólo funciona para gcc, que sería bueno para definir de esta manera para evitar errores en otros compiladores.

#ifdef __GNUC__ 
      __attribute__ ((format(printf, 2, 3))) 
#endif 
+2

Ese es un buen punto en general, pero no es un problema para mí, ya que se trata de una base de código interna construida con un flujo estricto. –

+3

También podría usar '#ifndef __GNUC__ #define __atributo __ (a)'. Entonces puedes usar cualquier atributo. – cubuspl42

2

Trate los miembros estáticos de la misma manera que los no miembros. La discusión me dio la respuesta, pero no vale de nada para los demás:

  • funciones que no son miembros trabajan con 1,2
  • métodos estáticos funcionan con 1,2
  • no estático funciones miembro tratan a 'esto' como # 1, por lo tanto necesitan 2,3

me encontré con esto porque tenemos algunos procesos que utilizan ayudantes de registro como este y 1 de cada 4 se requiere __attribute__ ((format(printf, 2, 3))) con la otra thr ee trabajar bien con __attribute__ ((format(printf, 1, 2))) - resultó que era no estático ...

Cuestiones relacionadas