IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Utilité du ## précédant __VA_ARGS__


Sujet :

C

  1. #1
    Membre émérite Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Par défaut Utilité du ## précédant __VA_ARGS__
    Quelle est l'utilité de mettre un ## ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    # define foo(a, ...) bar( a, ## __VA_ARGS__)
    Merci.

  2. #2
    Membre émérite Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Par défaut
    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 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    warning: ISO C99 requires rest arguments to be used
    D'après la doc de gcc ce comportement est compatible C99 mais j'avoue ne pas comprendre la nuance dans ce passage :
    Citation Envoyé par http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html
    Second, 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. This does not happen if you pass an empty argument, nor does it happen if the token preceding `##' is anything other than a comma.

    eprintf ("success!\n")
    ==> fprintf(stderr, "success!\n");

    The above explanation is ambiguous about the case where the only macro parameter is a variable arguments parameter, as it is meaningless to try to distinguish whether no argument at all is an empty argument or a missing argument. In this case the C99 standard is clear that the comma must remain, however the existing GCC extension used to swallow the comma. So CPP retains the comma when conforming to a specific C standard, and drops it otherwise.
    (entre "left out" et empty)

  3. #3
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    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.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  4. #4
    Membre émérite Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Par défaut
    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.

  5. #5
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Pourtant, j'ai du mal à voir précisément la différence entre ceci (en supposant l'extension GNU supportée) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    # define foo(a, ...) bar( a, ## __VA_ARGS__)
    Et ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    # define foo(...) bar(  __VA_ARGS__)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Membre émérite Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    #define foo(...) bar(a, __VA_ARGS__)

  7. #7
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par ssmario2 Voir le message
    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.
    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.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    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...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Utilité d'un pointeur vers une fonction ?
    Par Nasky dans le forum C
    Réponses: 10
    Dernier message: 20/03/2010, 19h54
  2. [J2EE] Utilité de la J2EE de SUN ?
    Par PeteMitchell dans le forum Java EE
    Réponses: 4
    Dernier message: 14/05/2004, 10h29
  3. [LG]Utilité du type enuméré ?
    Par tarbala dans le forum Langage
    Réponses: 2
    Dernier message: 10/12/2003, 16h20
  4. Le BIOS et son utilité
    Par le mage tophinus dans le forum Assembleur
    Réponses: 75
    Dernier message: 21/11/2003, 15h37
  5. utilité du binaire et hexadecimaux?
    Par souris78 dans le forum C
    Réponses: 9
    Dernier message: 01/07/2003, 15h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo