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 :

Macros et nombre d'arguments variable


Sujet :

C

  1. #1
    Membre régulier Avatar de kaisse
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    100
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 100
    Points : 117
    Points
    117
    Par défaut Macros et nombre d'arguments variable
    Bonjour,

    je développe en ce moment un module de gestion d'erreurs pour un IDE (petite pub: http://cworkshop.sourceforge.net/index.html). J'aimerais fournir une fonction qui affiche, en plus d'un message d'information sur une erreur, un maximum d'informations sur la provenance de l'erreur. J'utilise donc les macros standards __FILE__, __LINE__ et __func__. Je crée une fonction qui prend en paramètre le nom du fichier, la ligne et la fonction concernés, plus le texte à afficher et qui affiche tout ça. Puis je définis une macro qui fait que l'utilisateur a juste à préciser le texte qu'il souhaite voir afficher.

    Ca donne quelque chose comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    void fonction (char *file, int line, char *func, char *text);
    #define macro(text) fonction(__FILE__, __LINE__, __func__, text)
    Aucun soucis jusque-là. Maintenant, j'aimerais permettre aux développeurs de fournir des chaînes formatées à la printf. Donc le prototype de ma fonction devient:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    void fonction (char *file, int line, char *func, char *text, ...);
    Le problème, c'est que je ne peux pas transposer ça à une macro. J'ai donc envisager deux solutions:

    1 - Créer une macro distincte pour chaque nombre d'arguments:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    #define macro0(text) ...
    #define macro1(text, arg1) ...
    #define macro2(text, arg1, arg2) ...
    2 - Créer une fonction qui prend un nombre quelconque d'argument et renvoie une va_list:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    va_list args_to_va_list (char truc, ...);
    #define macro(text, list) ...
     
    /* utilisation */
    macro ("%s:%d\", args_to_va_list (0, texte, valeur));
    Inconvénient du premier: pas générique. Je peux créer par défaut 3 ou 4 macros, mais si jamais un développeur a besoin de beaucoup d'informations lors de sa séance de debuggage, il va par exemple créer une macro qui a besoin de 8 arguments. Sans compter si il a besoin au dernier moment de rajouter ou d'enlever quelques arguments .. on risque de vite devoir créer des macros pour aller jusqu'à 20 arguments. Celà dit une fois que c'est fait, c'est plus à faire, et ce cas est assez rare.

    Inconvénient du deuxième: écriture assez lourde et exigeante pour le développeur (alors que je suis sensé lui facilité la tâche).

    Solution intermédiaire: fournir des macros pour 0 à 3 arguments comme suggéré dans le premier cas, et fournir la macro du second cas aussi, pour les gros cas.

    Voilà, j'en appelais à vous pour savoir ce que vous pensiez de tout ça, si vous avez déjà eu ce genre de désagrément et auquel cas, savoir comment vous vous en étiez sorti. Si vous avez d'autres solutions je suis preneur.

  2. #2
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Juin 2004
    Messages
    68
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2004
    Messages : 68
    Points : 86
    Points
    86
    Par défaut
    et en passant par 2 variables globales?
    en gros comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    char* file_global;
    int line_global;
     
    void fonction(char* fmt, ...);
     
    #define macro file_global=__FILE__, line_global=__LINE__, fonction
     
    /* l'appel se ferait donc comme ceci */
     
    macro("to%s", "to");
    c'est ce tuto qui m'en a donné l'idée http://haypo.developpez.com/article/...#prototype_new notament la macro pour delete

  3. #3
    Membre régulier Avatar de kaisse
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    100
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 100
    Points : 117
    Points
    117
    Par défaut
    Merci bien, c'est l'idée qu'il me manquait . Je test ça de suite, et je réédite le message en cas de problèmes.

    Merci.

    EDIT: c'est parfait, merci encore pour l'astuce et le lien. Ca évite en plus d'ajouter plein d'arguments à la fonction, et du coup, la manipulation de la macro correspond bien au prototype de la fonction.

  4. #4
    Membre averti

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    289
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 289
    Points : 342
    Points
    342
    Par défaut
    Des variables globales, ce n'est pas très réentrant...
    En C99, les macros peuvent prendre un nombre variable de paramètres. Des exemples directement issus de la norme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define debug(...)   fprintf(stderr, __VA_ARGS__)
    #define report(test,...)    ((test)?puts(#test):printf(__VA_ARGS__))
    EDIT: capitN.flam < Nan mais si on se met à lire des cours de C++ pour apprendre le C, on ne va pas aller loin...

  5. #5
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Juin 2004
    Messages
    68
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2004
    Messages : 68
    Points : 86
    Points
    86
    Par défaut
    Citation Envoyé par alveric
    Des variables globales, ce n'est pas très réentrant...
    En C99, les macros peuvent prendre un nombre variable de paramètres. Des exemples directement issus de la norme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define debug(...)   fprintf(stderr, __VA_ARGS__)
    #define report(test,...)    ((test)?puts(#test):printf(__VA_ARGS__))
    EDIT: capitN.flam < Nan mais si on se met à lire des cours de C++ pour apprendre le C, on ne va pas aller loin...
    nan je te rassure je ne li pas un cours de C++ pour apprendre le C de plus ce cours est un cours mixte étant donné qu'il parle de malloc aussi. En fait je suis tombé sur ce cours en lisant ce thread. Je l'ai rapidement survolé mais ce problème de nombre d'argument sur delete m'a interpelé. Puis je suis tombé sur ce thread et je me suis dis que la solution pouvait fonctionner dans son cas aussi. J'ai fait un test rapide et je me suis effectivement rendu compte que cela pouvait fonctionner.

    En ce qui concerne le nombre variable de paramètre dans une macro je ne le savais pas et donc ne risquait pas de donner cette solution. Maintenant je le sais!!!

    Pour ma culture personnelle: que signifie réentrant?

  6. #6
    Membre averti

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    289
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 289
    Points : 342
    Points
    342
    Par défaut
    Citation Envoyé par capitN.flam
    Pour ma culture personnelle: que signifie réentrant?
    Au risque de me planter dans la définition exacte, je prends celle de http://en.wikipedia.org/wiki/Reentrant, mais c'est bien ce que je pensais: un code qui peut être partagé entre plusieurs threads/processus. Ca implique (entre autres ?) qu'il n'y ait pas de variable partagée, et que le code ne se modifie pas.

  7. #7
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Juin 2004
    Messages
    68
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2004
    Messages : 68
    Points : 86
    Points
    86
    Par défaut
    merci pour la definition et le lien. Effectivement je n'avais pas pensé aux threads cela peux effectivement posé problème.

  8. #8
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Salut
    je pense que ça peut t'aider : http://www.developpez.net/forums/viewtopic.php?t=229604

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Débutant] Nombre d'arguments variables
    Par akrodev dans le forum C++
    Réponses: 9
    Dernier message: 01/06/2006, 02h51
  2. Un script shell avec nombre d'argument variable
    Par lastrecrue dans le forum Linux
    Réponses: 1
    Dernier message: 28/05/2006, 11h35
  3. méthodes avec nombres d'arguments variable
    Par spynux dans le forum Langage
    Réponses: 2
    Dernier message: 26/05/2006, 13h51
  4. Réponses: 4
    Dernier message: 31/10/2005, 17h48
  5. Nombre d'arguments variable
    Par gege2061 dans le forum C
    Réponses: 7
    Dernier message: 05/08/2004, 15h43

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