2011-03-31 12 views
10

Esto me ha estado molestando desde hace algún tiempo, por ejemplo, si yo estoy tratando de escribir este código:gama Pases literal como argumento macro

// find the length of an array 
#define ARRAY_LENGTH(arr) (sizeof(arr)/sizeof(int)) 
// declare an array together with a variable containing the array's length 
#define ARRAY(name, arr) int name[] = arr; size_t name##_length = ARRAY_LENGTH(name); 

int main() { 
    ARRAY(myarr, {1, 2, 3}); 
} 

El código da este error:

<stdin>:8:31: error: macro "ARRAY" passed 4 arguments, but takes just 2 

Porque ve ARRAY(myarr, {1, 2, 3}); como ARRAY pasando el argumento myarr, {1, 2 y 3}. ¿Hay alguna manera de pasar una matriz literal a las macros?

EDITAR: En algunas de las macros más complejas que necesitaba, también podría necesitar pasar dos o más matrices a la macro, por lo que la macro variable no funciona.

Respuesta

21

Sí, {} no son paréntesis para el preprocesador. Simplemente puede proteger los argumentos mediante una macro ficticia

#define P99_PROTECT(...) __VA_ARGS__ 
ARRAY(myarr, P99_PROTECT({1, 2, 3})); 

Debería funcionar en su caso. Por eso tiene un primer nivel de () que protege el , de ser interpretado como separador de argumentos. Estos () de la macro llamada desaparecen en la expansión.

Consulte aquí para macros más sofisticadas que hacen statement unroling.

+0

¿Hay alguna manera de hacer esto sin C99 varargs? – Mehrdad

+0

17 años, y aún no hay preprocesador compatible con C99? Podría tener las macros 'PROTECT0',' PROTECT1' ... para la cantidad correcta de comas que tiene allí. –

+0

Supongo que quise decir algo menos doloroso, pero parece que no. – Mehrdad

Cuestiones relacionadas