2012-09-15 17 views
9
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__)) 
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "native-activity", __VA_ARGS__)) 

Esta es la definición de estas 2 macros; más adelante en el código LOGI y LOGW se utilizan de esta maneraA #define en C con tres puntos

LOGI("accelerometer: x=%f y=%f z=%f", 
           event.acceleration.x, event.acceleration.y, 
           event.acceleration.z); 

y de esta manera

LOGW("Unable to eglMakeCurrent"); 

Desde Trato de evitar las macros complejas y #define en general, no puedo conseguir lo que esto significa en realidad macro . ¿Cuál es el papel de la notación de 3 puntos aquí? ¿Qué hace que este #define cambie más adelante en el código?

Obviamente, sé que los 3 puntos se usan para indicar una cantidad indefinida de argumentos, pero no sé cómo leer esta situación.

+4

Se llama una macro variadic. http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html – chris

+0

@ Chris por lo que es una forma de tratar de ser menos detallado y reorganizar los argumentos de una manera determinada? – Ken

+0

Hmm, habría utilizado '## __ VA_ARGS__', pero supongo que está bien, siempre y cuando usted tiene que dar un argumento. – nneonneo

Respuesta

14

El estándar C99 introdujo macros variadicas, es decir, macros con funciones que pueden tomar un número variable de argumentos.

Citando la latest draft de la norma C, Sección 6.10.3:

Si el identificador-lista en la definición macro no termina con una elipsis , el número de argumentos (incluyendo aquellos argumentos que consiste de ningún token de preprocesamiento) en una invocación de una macro de función similar a deberá ser igual al número de parámetros en la definición macro . De lo contrario, habrá más argumentos en la invocación que hay parámetros en la definición de la macro (excluyendo el ...). Existirá a) un token de preproceso que finaliza la invocación .

El identificador de __VA_ARGS__ se producirá sólo en el reemplazo-lista de una macro-función como que utiliza la notación de puntos suspensivos en los parámetros .

...

Si hay una ... en el identificador-lista en la definición macro, luego los argumentos de cola, incluyendo cualquier tokens comas preprocesamiento de separación, se fusionan para formar una sola ítem: la variable argumentos. El número de argumentos así combinados es tal que, después de la fusión, el número de argumentos es uno más que el número de parámetros en la definición de macro (excluyendo el ...).

Y en la siguiente subsección:

Un identificador __VA_ARGS__ que se produce en la lista de reemplazo se ser tratados como si se tratara de un parámetro, y los argumentos variable formar los tokens de preprocesamiento utilizados para reemplázalo.

Así se puede invocar LOGI o LOGW con tantos argumentos como te gusta, y todos ellos estarán expandida en el lugar especificado en la definición por la referencia a __VA_ARGS__.

+0

Por cierto, es '## __ VA_ARGS__' (comúnmente usado para manejar el caso de cero argumentos proporcionado a una macro variadic) permitido por la norma? ¿Es incluso necesario? – nneonneo

+0

La notación '## __ VA_ARGS__' es una extensión de GCC. –

+0

Sí, es una extensión y puede reemplazarse por otras técnicas que cuenten el número de argumentos que recibe la macro. –

Cuestiones relacionadas