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 :

Déclaration de variable dans une macro


Sujet :

C

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 34
    Par défaut Déclaration de variable dans une macro
    Bonjour,

    Indépendamment de la propreté du code et de l'hérésie de procéder ainsi, soit le code suivant :

    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
     
    #define DEFINITION_VARIABLE(_type_, _valeur_) { \
      _type_ toto;   \
      toto = (_valeur_) * ((_valeur_) - 1); \
    }
     
    #define COMPARE_AFFECTE(_type2_, _valeur2_) { \
      if (toto > (_valeur2_)) \
        *sortie = (_type_2)toto: \
      else \
        *sortie = (_type_2)0; \
      return; \
    }
     
     
    void short2int(short entree, int * sortie)
    {
      DEFINITION_VARIABLE(short, entree - 2);
      COMPARE_AFFECTE(int, 125);
    }
     
    void short2long(short entree, long * sortie)
    {
      DEFINITION_VARIABLE(short, entree + 3);
      COMPARE_AFFECTE(long , 3254);
    }
     
    void uchar2short(unsigned char entree, short * sortie)
    {
      DEFINITION_VARIABLE(unsigned char, entree);
      COMPARE_AFFECTE(short , 17);
    }
    etc.

    Dans chacune de mes fonctions, je vais avoir pour COMPARE_AFFECTE le message d'erreur "variable toto non déclaré".
    J'avoue être surpris puisque je pensais naïvement que le pré-processeur faisait du copier / remplacer de macros avant la compilation.

    J'ai raté quelque chose ?

    Merci d'avance pour vos réponses.

  2. #2
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Bonjour,

    Je pense que le mieux dans ce cas est d'aller voir quelle est le code apres passage du preprocesseur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gcc -E mon_fichier.c > mon_fichier_preprocess.c
    [Edit]
    J'avais un peu de temps, j'ai fait le test. Tu as simplement un probleme de declaration de bloc : dans DEFINITION_VARIABLE, tu declares _toto_ dans un bloc ; donc a la fin du bloc, la variable toto n'existe plus.

    [Edit2]
    Tu as aussi un soucis dans ton code tu as _type2_ et _type_2 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #define COMPARE_AFFECTE(_type2_, _valeur2_) { \
      if (toto > (_valeur2_)) \
        *sortie = (_type_2)toto: \
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 34
    Par défaut [Résolu] Déclaration de variable dans une macro
    Citation Envoyé par gangsoleil Voir le message
    Bonjour,

    Je pense que le mieux dans ce cas est d'aller voir quelle est le code apres passage du preprocesseur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gcc -E mon_fichier.c > mon_fichier_preprocess.c
    [Edit]
    J'avais un peu de temps, j'ai fait le test. Tu as simplement un probleme de declaration de bloc : dans DEFINITION_VARIABLE, tu declares _toto_ dans un bloc ; donc a la fin du bloc, la variable toto n'existe plus.
    Oui, j'ai fini par comprendre tout à l'heure...
    On m'avait toujours appris de déclarer une macro avec { \ à la fin de la première ligne et } à la toute fin.
    En fait, si on retire les {}, ça marche.

    Citation Envoyé par gangsoleil Voir le message
    [Edit2]
    Tu as aussi un soucis dans ton code tu as _type2_ et _type_2 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #define COMPARE_AFFECTE(_type2_, _valeur2_) { \
      if (toto > (_valeur2_)) \
        *sortie = (_type_2)toto: \
    En fait, j'ai réécris un code d'exemple, je n'avais pas accès au code de base. Donc pas de souci de ce côté.
    Merci pour votre aide néanmoins.

  4. #4
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Bonjour,

    Citation Envoyé par olivier_u Voir le message
    On m'avait toujours appris de déclarer une macro avec { \ à la fin de la première ligne et } à la toute fin.
    En fait, si on retire les {}, ça marche.
    Comme les macro ne sont au final que du texte qui sera copié/généré dans le code par le pré-processeur, il faut vraiment se méfier des priorités :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define TOTO 5+4
    TOTO*5
    Donnera : 5+4*5 = 25 au lieu de (5+4)*5 = 45

    C'est pour cela qu'on conseille de mettre des parenthèses :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define TOTO (5+4)
    TOTO*5
    Donnera : (5+4)*5 = 45

    Le fait de mettre des accolades me semble un peu ridicule car à part provoquer des effets de bords, ta macro ne servira à rien.
    Dénonces-les, qui t'as dit de mettre systématiquement des accolades ?

  5. #5
    Membre actif
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 34
    Par défaut
    Citation Envoyé par Neckara Voir le message
    Bonjour,
    Le fait de mettre des accolades me semble un peu ridicule car à part provoquer des effets de bords, ta macro ne servira à rien.
    Dénonces-les, qui t'as dit de mettre systématiquement des accolades ?
    Celui qui nous initié en C, en école.
    Enfin, bon, c'était un peu bizarre aussi. Il considérait qu'à part 0 ou 1, aucune autre constante ne méritait d'être dans le code sans être déclarée en #define.
    Quant au macro, ils nous a dit ça mais nous a dit aussi de ne jamais nous en servir . Le C discipliné, qu'il a appelé ça. Il avait même écrit un compilateur spécial et qu'on devait utiliser pour qu'on respecte ses règles.

    De toute façon, c'est en industrie que j'ai vraiment appris le C et ses subtilités plus tard. L'inconvénient, c'est qu'on nous a toujours imposé l'ISO C89 ce qui fait que je suis un codeur d'il y a 20 ans

  6. #6
    Membre Expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Par défaut
    Le préproc' n'est jamais assez abordé, comme d'habitude, et toujours car il n'y a pas assez de temps pour faire du C et du préproc'...

    Le C ANSI/C89 a beau être "vieux", il n'en reste pas moins une norme tout à fait potable... excepté pour quelques fonctions (dommage...).
    Enfin bref : écrire du C89 n'est pas négatif du tout, car c'est l'une des rares normes "réellement" disponible sur quasiment toutes les architectures.
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  7. #7
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Citation Envoyé par olivier_u Voir le message
    Il considérait qu'à part 0 ou 1, aucune autre constante ne méritait d'être dans le code sans être déclarée en #define.
    Et c'est plutot une bonne chose.

    Lorsque tu ecris ton code, tu sais pourquoi tu mets telle valeur de constante ici, et telle autre la.
    Mais lorsque tu reprends ton code 3 mois plus tard, tu te demandes vite pourquoi tu fais for (i=0 ; i < 42 ; i++), alors que le truc auquel tu accedes a une taille variable d'au moins 50.
    Une constante nommee "NOMBRE_MAX_MACHINS" te dira que visiblement, dans ta variable, tu peux avoir au plus 42 machins (le reste etant des bidules)

    D'ailleurs, le fait de rencontrer des constantes en chiffres dans du code s'appelle parfois des "nombres magiques".


    L'inconvénient, c'est qu'on nous a toujours imposé l'ISO C89 ce qui fait que je suis un codeur d'il y a 20 ans
    C'est pas tres grave ca.

    Le C99 apporte quelques bonnes choses, mais le fait que beaucoup de compilateurs ne l'aient pas implementes dans son integralite pendant tres longtemps etait aussi un frein.
    Et puis si tu te retrouves a developper pour plusieurs cibles (ne serait-ce que plusieurs OS dont certains vieux), tu vas voir que l'avantage du C89 est qu'il compile partout.
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  8. #8
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Citation Envoyé par gangsoleil Voir le message
    Et c'est plutot une bonne chose.

    Lorsque tu ecris ton code, tu sais pourquoi tu mets telle valeur de constante ici, et telle autre la.
    Mais lorsque tu reprends ton code 3 mois plus tard, tu te demandes vite pourquoi tu fais for (i=0 ; i < 42 ; i++), alors que le truc auquel tu accedes a une taille variable d'au moins 50.
    Une constante nommee "NOMBRE_MAX_MACHINS" te dira que visiblement, dans ta variable, tu peux avoir au plus 42 machins (le reste etant des bidules)

    D'ailleurs, le fait de rencontrer des constantes en chiffres dans du code s'appelle parfois des "nombres magiques".
    Il faut aussi nuancer, pour certains cas utiliser des #define est une abhération :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AireTriangleRectangle = hauteur*longueur/2
    Je pense que ce serait horrible d'utiliser un #define ici, sinon on se retrouvera assez vite avec des :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define DEUX 2
    #define SEIZE_VIRGULE_QUATRE 16.4


    Donc oui, il faut éviter les nombres magiques mais se les interdire en toute circonstance est une abhération.

  9. #9
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Citation Envoyé par Neckara Voir le message
    Bonjour,
    ...
    Le fait de mettre des accolades me semble un peu ridicule car à part provoquer des effets de bords, ta macro ne servira à rien.
    Dénonces-les, qui t'as dit de mettre systématiquement des accolades ?
    Bonjour,

    les accolades ont l'avantages de pouvoir créer des blocs de code plus ou moins indépendants de leur localisation, les variables crées locales à ce bloc etc ...
    Une sorte de manière de créer des fonctions inlines avec pleins de désavantages en fait.
    Pour être encore plus proche de la syntaxe des fonctions on peut imaginer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #define mamacro(x,y) do {\
                             le corps de la "fonction" \
                         } while(0)
    Le pseudo avantage d'entourer le code par un do {} while(0) et de pouvoir ensuite utiliser la macro comme une "fonction retournant void" «avec le point virgule à la fin» : mamacro(1,x);

    Depuis la disponibilité des fonctions inline cela n'a plus grand intérêt en pratique quotidienne.

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

Discussions similaires

  1. Déclaration de variables dans une procédure stockée
    Par jbrasselet dans le forum Développement
    Réponses: 5
    Dernier message: 16/02/2009, 09h00
  2. déclaration des variables dans une fonction
    Par kawther dans le forum Débuter
    Réponses: 4
    Dernier message: 22/10/2008, 01h17
  3. Paramètres variables dans une macro
    Par muad'dib dans le forum C
    Réponses: 7
    Dernier message: 21/01/2008, 19h56
  4. Variable dans une macro
    Par euskal75 dans le forum IHM
    Réponses: 2
    Dernier message: 05/12/2007, 17h11
  5. Réponses: 8
    Dernier message: 03/11/2006, 15h55

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