Il existe un bien connu problème avec des arguments vides pour les macros variadiques en C99.
exemple :
#define FOO(...) printf(__VA_ARGS__)
#define BAR(fmt, ...) printf(fmt, __VA_ARGS__)
FOO("this works fine");
BAR("this breaks!");
L'utilisation de BAR()
ci-dessus est en effet incorrect selon la norme C99, puisqu'il se développera en :
printf("this breaks!",);
Notez la virgule de fin de phrase - ce n'est pas possible.
Certains compilateurs (par exemple, Visual Studio 2010) se débarrasseront discrètement de cette virgule de fin pour vous. D'autres compilateurs (par exemple, GCC) prennent en charge la mise en place de la virgule de fin. ##
devant __VA_ARGS__
comme ça :
#define BAR(fmt, ...) printf(fmt, ##__VA_ARGS__)
Mais existe-t-il un moyen conforme aux normes d'obtenir ce comportement ? Peut-être en utilisant plusieurs macros ?
En ce moment, le ##
semble assez bien supportée (du moins sur mes plateformes), mais je préférerais vraiment utiliser une solution conforme aux normes.
Préventif : Je sais que je pourrais simplement écrire une petite fonction. J'essaie de le faire en utilisant des macros.
Editar : Voici un exemple (bien que simple) de la raison pour laquelle je voudrais utiliser BAR() :
#define BAR(fmt, ...) printf(fmt "\n", ##__VA_ARGS__)
BAR("here is a log message");
BAR("here is a log message with a param: %d", 42);
Cela ajoute automatiquement une nouvelle ligne à mes instructions de journalisation BAR(), en supposant que fmt
est toujours une chaîne de caractères C doublement citée. Il n'imprime PAS la nouvelle ligne comme un printf() séparé, ce qui est avantageux si l'enregistrement est tamponné par ligne et provient de plusieurs sources de manière asynchrone.
3 votes
Pourquoi utiliser
BAR
au lieu deFOO
en premier lieu ?0 votes
@GMan : J'ai ajouté un exemple à la fin.
0 votes
Dans ce cas, il suffit d'utiliser une macro multi-états avec une balise
printf("\n");
à la fin.6 votes
@GMan : Lisez la dernière phrase ( :
7 votes
Cette fonction a été proposé pour être inclus en C2x.
0 votes
@Leushenko Connaîtriez-vous par hasard le statut de cette proposition à l'heure actuelle (un peu plus d'un an après) ?
3 votes
@zwol la dernière version soumise au WG14 ressemble à ceci qui utilise une nouvelle syntaxe basée sur l'approche de la
__VA_OPT__
mot-clé. Ce site a déjà été "adoptée" par le C++, et je m'attends donc à ce que le C fasse de même. (Je ne sais pas si cela signifie qu'il a été intégré rapidement au C++17 ou s'il est prévu pour le C++20).