56Fermer58
squalylLe 11/11/2014 à 10:57
le ## en general il sert a la concatenation de tokens

genre

#define prefix plop
#define funcname(suffix) prefix ## suffix

funcname(boo) fera plopboo

c'est le seul moyen de coller 2 arguments de macro.

MAIS avec __VA_ARGS__ il a un role special:

http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html

Normalement tu veux ecrire comme ca:

You can have named arguments as well as variable arguments in a variadic macro. We could define eprintf like this, instead:

#define eprintf(format, ...) fprintf (stderr, format, __VA_ARGS__)

MAIS grosse contrainte, VA_ARGS peut pas etre vide:

unfortunately it is less flexible: you must now supply at least one argument after the format string.

Oblige d'avoir un argument. Donc pour contourner:

the ‘##’ token paste operator has a special meaning when placed between a comma and a variable argument. If you write

#define eprintf(format, ...) fprintf (stderr, format, ##__VA_ARGS__)

and the variable argument is left out when the eprintf macro is used, then the comma before the ‘##’ will be deleted.

Donc ##__VA_ARGS__ sert a virer la virgule qui te fait chier quand y'a pas de VA_ARGS grin

ta macro n'est donc toujours pas bonne. Ce que tu veux, c'est ca:

#define CHECK(condition, label, fmt, ...)                                  \
  if (!(condition)) {                                                 \
    fprintf(stderr, "%s, %s, %i\n", __FILE__, __func__, __LINE__);    \
    fprintf(stderr, fmt, ##__VA_ARGS__);                               \
    goto label;                                                       \
  }


et ca s'utilise:

CHECK(pernawel, pluzungoss, "la mere nawel est triste");
CHECK(pernawel, pluzungoss, "la mere nawel est triste, il est parti depuis %d jours", jours);