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 :

#define conditionnel à problème


Sujet :

C

  1. #1
    Membre émérite
    Avatar de bpy1401
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2003
    Messages
    511
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2003
    Messages : 511
    Par défaut #define conditionnel à problème
    Bonjour à tous.

    je cherche à faire une macro conditionnelle et comme ce terme n'est pas clair un petit exemple va être plus compréhensible

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #define MA_MACRO(name) \
       #ifdef ALREADY_DEFINE_##name \
       printf("%s est deja definie\n",name); \
       #else \
       printf("%s n'est pas defini\n",name); \
       #endif
    bien évidemment, mon préprocesseur n'apprécie pas le #ifdef dans un #define
    Qui pourrais me donner une idée pour résoudre le problème

    merci d'avance
    Page sur Developpez : http://pbriand.developpez.com

  2. #2
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    bonjour,

    moi je le ferais dans l'autre sens. Quelque chose du style:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #ifdef ALREADY_DEFINE
       #define MA_MACRO(name) printf("%s est deja definie\n",name);
    #else
       #define MA_MACRO(name) printf("%s n'est pas defini\n",name);
    #endif

  3. #3
    Membre émérite
    Avatar de bpy1401
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2003
    Messages
    511
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2003
    Messages : 511
    Par défaut
    Bonjour,

    je ne peux pas dans ce sens car le #ifdef prend en compte un des paramètres de la macro (paramètre name).

    #define MA_MACRO(name) \
    #ifdef ALREADY_DEFINE_##name \
    Page sur Developpez : http://pbriand.developpez.com

  4. #4
    Membre émérite
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Par défaut
    Concrètement je ne crois pas que ce soit possible.
    Parce que les directives de préprocesseur sont évaluées à la compilation et non à l'exécution. De ce fait faire un #ifdef avec une variable n'a pas de sens

    Seule la déclaration de r0d est correcte, parce que #ifdef ALREADY_DEFINE peut être évaluée à la compilation

  5. #5
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    A mon avis, ce n'est pas possible de faire ce que tu veux faire ici. La première question qui me vient à l'esprit est pourquoi veux-tu faire cela? Il y a peut-être (certainement) une meilleures solution.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  6. #6
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Effectivement, j'ai beau tourner le problème dans tous les sens, je ne vois pas de solution.
    Ne pourrais-tu pas faire ce que tu veux en utilisant une structure instanciée en global?

  7. #7
    Membre Expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    Citation Envoyé par r0d Voir le message
    Effectivement, j'ai beau tourner le problème dans tous les sens, je ne vois pas de solution.
    Ne pourrais-tu pas faire ce que tu veux en utilisant une structure instanciée en global?
    Et pour le printf peu etre que (je suis un peu rouillé)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #define MA_MACRO(name) printf(#name" est deja definie\n");
    Tu as aussi la possibilité de placer des warning/erreurs de compile
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    #warning "un message"
    #error  "un message"

  8. #8
    Membre émérite
    Avatar de bpy1401
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2003
    Messages
    511
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2003
    Messages : 511
    Par défaut
    Bonjour à tous

    merci pour vos réponse.

    En fait, le fichier H est un fichier généré automatiquement par un outil à partir d'un fichier EXCEL. La macro doit faire appel à une fonction si NAME est défini dans le fichier EXCEL, car on doit dans ce cas faire appel à une fonction bien spécfique, sinon on doit sauvegarder une valeur dans une variable globale nommée NAME. L'exemple que j'ai donné est juste pour décrire ce que je souhaitais faire, il n'y aura pas de printf dans l'application.

    Dans la version précédente du logiciel, des que l'on tombait sur un NAME inexistant, on devait rajouter manuellement la copie de la variable dans le fichier .h, et comme le nombre de cas se multiplie, cela devient très lourd à gérer, d'ou l'idée d'un macro qui s'adapte à l'existance ou nom d'un define.

    Je ne peux pas vous donner la vrai code, mais voici un exemple plus parlant

    le fichier H auto généré
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
       /* ------------------------------ */ 
       /* Partie générée automatiquement */
       /* ------------------------------ */
      #define VAR_UneVariable      1
      #define VAR_UneAutreVariable 1
     
      /* Fonction d'assignation de UneVariable */
      #define VAR_SET_UneVariable(value) \
          set_value_UneVariable(value)
     
      /* Fonction d'assignation de UneAutreVariable */
      #define VAR_SET_UneVariable(value) \
          send_value_UneAutreVariable(value)
     
     
      /* Macro générique pour l'assignataion des variables */ 
      #define ASSIGN_SET(name,value) 
        #ifdef VAR_##name
          VAR_SET_##name(value)
        #else
          name = value
        #endif
    et un .C utilisant ce .h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    #include "Assign.h"
     
    int LocalVariable;
     
    void set_value_UneVariable(int val) 
    {
    }
     
    void send_value_UneAutreVariable(int val) 
    {
    }
     
    void main(void) 
    {
      ASSIGN_SET(UneVariable,1);
      ASSIGN_SET(UneAutreVariable,1);
      ASSIGN_SET(LocalVariable,1);
    }
    J'espère que mon explication est plus clair
    Page sur Developpez : http://pbriand.developpez.com

  9. #9
    Membre émérite
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Par défaut
    Comme je t'ai dis plus haut « les directives de préprocesseur sont évaluées à la compilation et non à l'exécution. ».
    Donc ce que tu veux faire est incorrect. Il faut que tu trouves autre chose

    C'est un peu comme si tu voulais faire ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if (1) {
    #define N 10
    }
    else {
    #define N 20
    }
    Normalement ton compilateur doit te mettre un joli message d'erreur en te disant que N est déjà déclaré

  10. #10
    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
    C'est bien au préprocesseur que briand patrick veut faire son test.

    Malheureusement, il est à ma connaissance impossible d'inclure un #if dans un #define. J'ai moi-même été confronté à un problème de ce genre...
    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.

  11. #11
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par briand patrick Voir le message
    bien évidemment, mon préprocesseur n'apprécie pas le #ifdef dans un #define
    je pense que ce qu'il n'appréie pas, c'est les blancs (espaces) devant..

    Il est tout à fait possible de faire :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #ifdef TOTO /* Cas ou TOTO est defini */
    #ifdef TATA /* Cas ou TATA et TOTO sont defini */
    fprintf ( stderr, "TITI");
    #else  /* cas ou TATA n'est pas defini mais TOTO l'est */
    fprintf ( stderr, "TUTU");
    #endif
    #else /* Cas ou TOTO n'est pas defini */
    fprintf ( stderr, "TUTLUTUTU");
    #endif

    Mais le pré-processeur n'accepte les #if, #ifdef, #else, etc, que en PREMIERE colonne....

  12. #12
    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
    Citation Envoyé par souviron34 Voir le message
    je pense que ce qu'il n'appréie pas, c'est les blancs (espaces) devant..
    <snip>
    Mais le pré-processeur n'accepte les #if, #ifdef, #else, etc, que en PREMIERE colonne....
    C'est dans la norme, ça?

    Je viens de tester, Visual et gcc acceptent aussi bien #if que (tab)#if, et même #(tab)if...
    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.

  13. #13
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    C'est dans la norme, ça?
    aucune idée, mais je me souviens m'être fait jeter plusieurs fois....

    Sinon, je suis également certain qu'il n'apprécie pas ceci :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    #ifdef ALREADY_DEFINE_##name

    Puisque on est en pré-compilation, name n'est pas défini et donc ce ifdef ne correspond pas à une constante...


    Maintenant, je crois que je comprend ce que veux faire le PO, et c'est impossible : je pense qu'il veut pouvoir tester (au runtime) si tel ou tel symbole est défini en le construisant dynamiquement....

  14. #14
    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
    Non, il veut bien le faire en compile-time, mais c'est impossible aussi.

    Un exemple simplifié, imagine qu'il veut obtenir ceci:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    switch(toto)
    {
    #ifdef DEF_A
    case DEF_A: return "DEF_A";
    #endif
    #ifdef DEF_B
    case DEF_B: return "DEF_B";
    #endif
    #ifdef DEF_C
    case DEF_C: return "DEF_C";
    #endif
    }
    À partir de ceci:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    switch(toto)
    {
    #define ITEM (quelque chose)
    #include "DEFs.itm"
    #undef ITEM
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    /*DEFs.itm*/
    ITEM(DEF_A)
    ITEM(DEF_B)
    ITEM(DEF_C)
    C'est une chose que j'ai moi-même essayé de faire, avec toutes les valeurs des codes d'erreur de Windows: J'ai été obligé de mettre les #ifdef, à cause des différentes versions du SDK.
    En gros, un #define dont l'expansion donne des #ifdef.

    Réponse:
    ...Et bien je n'ai pas pu le faire, j'ai du passer mon .itm dans une moulinette pour en faire ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    /*DEFs2.itm*/
    #ifdef DEF_A
    ITEM(DEF_A)
    #endif
    #ifdef DEF_B
    ITEM(DEF_B)
    #endif
    #ifdef DEF_C
    ITEM(DEF_C)
    #endif
    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.

  15. #15
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    mais c'est absolument évident !!!

    un #define définit une constante, stockée à un certain endroit par le compilo..mais il n'éxécute pas de code.. sauf les quelques instructions définies par les #...


    Il n'y a pas besoin de se torturer la cervelle..

    Il y a tout simplement une erreur de conception si on veut faire ce genre de choses...


    Dans ton exemple des erreurs, il doit y avoir quelque part un GetError (comme le errno) qui te retourne un entier..

    A toi de faire un switch ensuite,


    J'avoue être dans l'incompréhension la plus totale par rapport à ce qu'on pourrait vouloir faire avec ceci...

  16. #16
    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
    Tu n'as pas compris, ça utilise déjà le résultat entier de GetErreur(), c'est déjà pour un switch, et c'est déjà statique.

    C'est juste qu'on peut avoir envie d'utiliser une item-list au lieu de se taper tous les case manuellement. Et comme les trucs ne sont pas toujours définis...

    Dans le code du posteur originel, c'est le même schéma:
    • POUR chaque élément
      • SI macro_correspondant_a_cet_element est #défini
        • utiliser la macro
      • SINON
        • autre chose


    Bien sûr, je sais que c'est impossible, mais ce n'est pas une raison pour dire qu'avoir envie de le faire est une erreur.
    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.

  17. #17
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    désolé je continue à ne pas comprendre....


    Mais si je reprends l'exemple donné par le PO, je crois que ce qui pêche c'est (encore une fois ) vouloir faire de l'objet avec du C.. (ce que visiblement fait la traduction automatique du .h)

    Plus une (très) mauvaise utilisation de macros (qui a fait fureur dans certains milieux au début des années 90).. Définir des appels de fonctions par macro... J'ai eu à travailler sur un code comme ça et c'est une horreur absolue.... En particulier pour la lecture et le debug... (il faut se référer en permanence au .h pour savoir ce que fait cette macro particulière, et en debug pas à pas c'est un enfer : tu penses que c'est une fonction, donc tu fais "step in", et ça te jette... et quand en plus cela sert à appeler une fonction commune avec des paramètres particuliers, n'en parlons pas...).




    Quand on lit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     /* Fonction d'assignation de UneVariable */
      #define VAR_SET_UneVariable(value) \
          set_value_UneVariable(value)
     
      /* Fonction d'assignation de UneAutreVariable */
      #define VAR_SET_UneVariable(value) \
          send_value_UneAutreVariable(value)

    L'écriture de ces fonctions est une manière de penser Objet (une méthode par type d'objet), alors qu'une manière C serait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     /* Fonction d'assignation de une variable */
          set_value_Variable(int IndicVariable, value);
    où on n'a absolument pas besoin de faire toutes ces manipulations... C'est donc bien ce que je disais une erreur de conception fondamentale...


    Maintenant, si on ne peut pas modifier le .h, alors il n'y a qu'une seule manière simple et lisible et efficace de faire ce qu'on veut, c'est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void SetVariable ( int TypeVariable, void *Value)
    { 
       switch ( TypeVariable )
        {
            case  VAR_UneVariable  :
                 VAR_SET_UneVariable(value) ;
                 break ;
     
            case  VAR_UneAutreVariable  :
                 VAR_SET_UneAutreVariable(value) ;
                 break ;
        }
    }
    Le reste est de la jonglerie intellectuelle qui ne fait que compliquer la lecture du code (qui à cause de cette manière est de toutes façons déjà trop compliqué).


    Et quand tu dis "on peut avoir envie d'utiliser une item-list", mais tu fais exactement un switch-case.. Alors peut-être que pour toi , dans ton esprit, tu le vois autrement, mais quand je lis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    /*DEFs2.itm*/
    #ifdef DEF_A
    ITEM(DEF_A)
    #endif
    #ifdef DEF_B
    ITEM(DEF_B)
    #endif
    #ifdef DEF_C
    ITEM(DEF_C)
    #endif
    je ne vois rien d'autre qu'un switch fait par le préprocesseur... Et en terme de nombre de caractères entrés par toi, c'est le même... donc je ne vois pas le gain...

    Et si on veut le faire dynamiquement, ça ne marche pas..

    La seule manière dynamique est celle du vrai switch...

    Alors où on ne ne fait pas de define, et on a un indicateur entier (un tableau), ou on a des define, et la solution normale est le switch..

    Ton exemple est une fonction ITEM..

    Eh bien cette fonction est simple : ITEM(int)..

    Pourquoi vouloir la "surcharger" ????

  18. #18
    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
    Je saute la première partie de ton argumentaire, car je ne suis pas sûr d'avoir raison ou non sur la pertinence de ce modèle.

    Citation Envoyé par souviron34 Voir le message
    Et quand tu dis "on peut avoir envie d'utiliser une item-list", mais tu fais exactement un switch-case.. Alors peut-être que pour toi , dans ton esprit, tu le vois autrement, mais quand je lis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    /*DEFs2.itm*/
    #ifdef DEF_A
    ITEM(DEF_A)
    #endif
    #ifdef DEF_B
    ITEM(DEF_B)
    #endif
    #ifdef DEF_C
    ITEM(DEF_C)
    #endif
    je ne vois rien d'autre qu'un switch fait par le préprocesseur...
    Pour le préprocesseur lui-même, ça n'est pas un switch, vu que toutes les valeurs peuvent être définies à la fois (dans mon cas pour les erreurs, c'est le cas si on a un SDK à jour). Mais ça sert à écrire le code C d'un switch.
    Et en terme de nombre de caractères entrés par toi, c'est le même... donc je ne vois pas le gain...
    C'est le même parce ce qu'on cherche à faire est impossible. Mais ça permet aussi de faire autre chose qu'un simple switch dans le code. L'intéret d'une item-list, c'est qu'elle est réutilisable. Le problème de celle-ci, c'est qu'on n'est pas sûr que chaque élément existe.

    Et si on veut le faire dynamiquement, ça ne marche pas..

    La seule manière dynamique est celle du vrai switch...

    Alors où on ne ne fait pas de define, et on a un indicateur entier (un tableau), ou on a des define, et la solution normale est le switch..
    Mais mon code utilise un vrai switch. C'est juste qu'on le peuple avec une item-list réutilisable, plutôt qu'écrire chaque case à la main.

    Ton exemple est une fonction ITEM..

    Eh bien cette fonction est simple : ITEM(int)..

    Pourquoi vouloir la "surcharger" ????
    Dans le cas présent, ITEM est forcément une macro, vu que j'y emploie l'opérateur #.


    En gros, ce que je voulais, c'est pouvoir faire ceci:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    switch(errorCode)
    {
    case ERROR_FILE_NOT_FOUND: return "ERROR_FILE_NOT_FOUND";
    case ERROR_ACCESS_DENIED: return "ERROR_ACCESS_DENIED";
    #ifdef SOME_ERROR_DEFINED_IN_THE_LAST_SDK_VERSION
    case SOME_ERROR_DEFINED_IN_THE_LAST_SDK_VERSION: return "SOME_ERROR_DEFINED_IN_THE_LAST_SDK_VERSION";
    #endif
    }
    Sans avoir à me taper tout à la main, et accessoirement en pouvant réutiliser la liste des defines d'erreur (récupérée sur MSDN) autre part.
    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.

  19. #19
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    ce que je maintiens, c'est que d'une part tu tapes plus de code, pour quelque chose qui n'est pas plus utilisable...


    Et si vraiment tu veux faire ce que tu dis et être réutilisable, alors pourquoi simplement ne pas faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    int ErrorCodes[]={
                             ERROR_FILE_NOT_FOUND,
                             ERROR_ACCESS_DENIED
    #ifdef SOME_ERROR_DEFINED_IN_THE_LAST_SDK_VERSION
                             ,
                             SOME_ERROR_DEFINED_IN_THE_LAST_SDK_VERSION
    #endif
                             };
    char *Messages[]={
                             "ERROR_FILE_NOT_FOUND",
                             "ERROR_ACCESS_DENIED"
    #ifdef SOME_ERROR_DEFINED_IN_THE_LAST_SDK_VERSION
                             ,
                             "SOME_ERROR_DEFINED_IN_THE_LAST_SDK_VERSION"
    #endif
                             }
     
     
    int FindIndexOfCode ( int Code)
    {
      int i =0;
     
       while ( ErrorCodes[i] != Code )
         i++ ;
     
       return i ; 
    }
     
    void PrintError( int code)
    {
       int icode ;
     
       icode = FindIndexOfCode(code);
       fprintf (stderr, "%s\n", Messages[icode]);
    }
    ou, si tu le veux dynamique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    int CodeErrors[MAX_ERREURS_MON_PROG], NCodes=0 ;
    char *Messages[MAX_ERREURS_MON_PROG] ;
     
    void RegisterCode ( int Code, char *Message )
    {
        CodeErrors[NCodes] = Code ;
        Messages[NCodes] = strdup ( Message);
    }
     
    int FindIndexOfCode ( int Code)
    {
      int i =0;
     
       while ( CodeErrors[i] != Code )
         i++ ;
     
       return i ; 
    }
     
    void PrintError( int code)
    {
       int icode ;
     
       icode = FindIndexOfCode(code);
       fprintf (stderr, "%s\n", Messages[icode]);
    }

    et dans ton main ou ailleurs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int main ( void )
    {
    ....
     RegisterCode (ERROR_FILE_NOT_FOUND, "ERROR_FILE_NOT_FOUND");
     RegisterCode ( ERROR_ACCESS_DENIED, "ERROR_ACCESS_DENIED");
    #ifdef SOME_ERROR_DEFINED_IN_THE_LAST_SDK_VERSION
      RegisterCode (SOME_ERROR_DEFINED_IN_THE_LAST_SDK_VERSION,
                        "SOME_ERROR_DEFINED_IN_THE_LAST_SDK_VERSION");
    #endif
    }

  20. #20
    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
    Je me moque du dynamique.

    Le problème, c'est que ton truc est encore plus long à faire que les item-lists, surtout si je génère l'item-list pleine de #ifdef à partir de la première.

    En fait, j'ai fini par me faire directement un programme qui partait de ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ERROR_FILE_NOT_FOUND
    ERROR_ACCESS_DENIED
    SOME_ERROR_DEFINED_IN_THE_LAST_SDK_VERSION
    Pour me générer ça.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #ifdef ERROR_FILE_NOT_FOUND
    ITEM(ERROR_FILE_NOT_FOUND)
    #endif
    #ifdef ERROR_ACCESS_DENIED
    ITEM(ERROR_ACCESS_DENIED)
    #endif
    #ifdef SOME_ERROR_DEFINED_IN_THE_LAST_SDK_VERSION
    ITEM(SOME_ERROR_DEFINED_IN_THE_LAST_SDK_VERSION)
    #endif
    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. problème avec const char * et #define macro
    Par CodeurNé dans le forum C
    Réponses: 5
    Dernier message: 20/09/2006, 21h25
  2. [W3C] problème avec "id already defined"
    Par mussara dans le forum Balisage (X)HTML et validation W3C
    Réponses: 9
    Dernier message: 05/07/2006, 00h16
  3. Réponses: 6
    Dernier message: 20/06/2006, 14h49
  4. [XSL] Problème "Entity not defined"
    Par FreeCake dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 11/04/2006, 21h36
  5. D6: Problème de $DEFINE $IFDEF
    Par david_chardonnet dans le forum Langage
    Réponses: 6
    Dernier message: 22/02/2006, 16h27

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