Quelle est l'utilité de mettre un ## ici :
Merci.Code:# define foo(a, ...) bar( a, ## __VA_ARGS__)
Version imprimable
Quelle est l'utilité de mettre un ## ici :
Merci.Code:# define foo(a, ...) bar( a, ## __VA_ARGS__)
C'est pour supprimer la virgule en fin de liste si aucun argument n'est fourni (hormis le a).
La question maintenant est : ceci est-il spécifique à gcc ?
car en compilons avec -std=c99 -pedantic la virgule est supprimée mais j'ai un warning :
D'après la doc de gcc ce comportement est compatible C99 mais j'avoue ne pas comprendre la nuance dans ce passage :Code:warning: ISO C99 requires rest arguments to be used
(entre "left out" et empty)Citation:
Envoyé par http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html
Sous Visual Studio, la virgule est automatiquement éliminée si l'argument variable est vide : Référence MSDN.
Ensuite, comme le "##" est utilisé pour concaténer des tokens (Référence MSDN), il ne devrait pas poser le moindre souci au final étant donné qu'il sera simplement éliminé grâce aux espaces entourant le "##"...
Ceci étant dit, normalement, tu n'es pas censé passer un argument vide à une macro variadique, comme te l'indique le warning que tu as eu qui te demande d'utiliser le paramètre...
Chaque compilateur semble donc suivre sa propre règle à ce sujet, il se trouve que Visual supporte celle de GCC, mais pas l'inverse. L'idéal resterait quand même d'éviter les arguments variables vides afin d'être plus conforme au standard.
Je n'ai pas eu le réflex de vérifier sur MSDN...
Maintenant si Visual supporte la manière de faire de GCC tant mieux, je pense que la meilleure décision à faire et d'utiliser le ##, puisque je ne peux pas assurer qu'au moins un argument optionnel seras passé à ma macro.
Merci.
Pourtant, j'ai du mal à voir précisément la différence entre ceci (en supposant l'extension GNU supportée) :
Et ceci:Code:# define foo(a, ...) bar( a, ## __VA_ARGS__)
:?Code:# define foo(...) bar( __VA_ARGS__)
Le premier suppose un paramètre formel + des paramètres optionnels.
C'est juste le premier cas qui pose problème en l'absence de paramètres optionnels. Sans le ## la virgule ne serait pas supprimée.
ou alors j'ai mal compris ta réflexion et dans ce cas pour mieux illustrer les choses c'est ceci qui pose problème :
Code:#define foo(...) bar(a, __VA_ARGS__)
La technique habituelle consiste à utiliser une macro avec un nom spécial pour la variante sans paramètres variables... Par exemple, "foo0", le zéro indiquant "zéro paramètres".
Car n'oublie pas : ne pas passer de paramètres variables alors qu'on les a définis est en dehors des spécifications, donc potentiellement non-portable et non-supporté par les compilateurs.
Mais je trouve que c'est la spécification (qui a toujours raison) qui est mal faite dans ce cas, vu que les fonctions variadiques acceptent d'être appelées sans paramètres variables...