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 :

Guru of the Week n° 32 : les macros préprocesseurs


Sujet :

C++

  1. #1
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut Guru of the Week n° 32 : les macros préprocesseurs
    Voici une nouvelle traduction des Guru of the Week.

    Dans cet article, Herb Sutter aborde la question de l'utilité des macros préprocesseurs et s'ils sont encore utiles, dans quelles conditions.

    Guru of the Week n° 32 : les macros préprocesseurs

    EDIT : Retrouvez la liste de tous les Guru of the Week sur la page d'index.

    Bonne lecture.

    Utilisez-vous encore les macros et pour quelles utilisations ?

  2. #2
    Membre éclairé Avatar de seeme
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    430
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 430
    Points : 791
    Points
    791
    Par défaut
    J'ai un peu de mal à voir en quoi les utilisations présentées ici sont subtiles.. Classiques au mieux.

    Rien de neuf je trouve, (c'est le premier Guru que je lis je m'attendais à quelque chose d'un peu plus barbu...).

    Ca aurait été bien de parler aussi un peu des inconvénients à l'utilisation des macros trop complexes par exemple (debugger un code truffé de macro trop complexes et illisibles, c'est pas tip top).

    Oui, j'utilise les macros très régulièrement (même pour du c++). Pour protéger les déclaration des headers, très peu pour du plateform specific (il vaut mieux utiliser une couche d'abstraction ou des factories qu'un #ifdef _PC par exemple). Comme précisé dans l'article si le delta est ridicule (une ligne de plus sur PS3, pas besoin de faire une abstraction pour un cas aussi isolé par exemple) ça peut aider.

    Un exemple très intéressent que j'ai vu consiste à utiliser des macro pour décrire des structures de fichiers xml. Du coup ça permet en quelque lignes de créer toutes les structures, les tableaux, les hashmaps et tout le code de chargement. Pour un logiciel data-driven, c'est le top de pouvoir ajouter une ressource en quelques minutes. Par contre ça rejoint ce que je disais, il faut être sûr de ses macros sous peine de se taper du debug dans des lignes pleines de ## assez imbitables.

  3. #3
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Citation Envoyé par seeme Voir le message
    J'ai un peu de mal à voir en quoi les utilisations présentées ici sont subtiles.. Classiques au mieux.

    Rien de neuf je trouve, (c'est le premier Guru que je lis je m'attendais à quelque chose d'un peu plus barbu...).
    Oui, c'est du très classique
    Il ne faut pas oublié que ce GotW date de 1998 et qu'il est classé en difficulté 4 / 10 (donc relativement facile). Cela fait partie des bonnes pratiques depuis longtemps et c'est donc quelque chose de bien connu. (donc j'ai pas de doute que tu connaisses déjà ça )
    Mais cela reste des notions importantes pour ceux qui débutent ou ceux qui n'ont pas eu l'occasion d'étudier ce genre de chose.

    Citation Envoyé par seeme Voir le message
    Ca aurait été bien de parler aussi un peu des inconvénients à l'utilisation des macros trop complexes par exemple (debugger un code truffé de macro trop complexes et illisibles, c'est pas tip top).

    Oui, j'utilise les macros très régulièrement (même pour du c++). Pour protéger les déclaration des headers, très peu pour du plateform specific (il vaut mieux utiliser une couche d'abstraction ou des factories qu'un #ifdef _PC par exemple). Comme précisé dans l'article si le delta est ridicule (une ligne de plus sur PS3, pas besoin de faire une abstraction pour un cas aussi isolé par exemple) ça peut aider.

    Un exemple très intéressent que j'ai vu consiste à utiliser des macro pour décrire des structures de fichiers xml. Du coup ça permet en quelque lignes de créer toutes les structures, les tableaux, les hashmaps et tout le code de chargement. Pour un logiciel data-driven, c'est le top de pouvoir ajouter une ressource en quelques minutes. Par contre ça rejoint ce que je disais, il faut être sûr de ses macros sous peine de se taper du debug dans des lignes pleines de ## assez imbitables.
    Ok pour l'intérêt d'avoir une syntaxe simplifiée pour décrire les structures xml (et cela peut s'appliquer à d'autres cas). Par contre, je préfère la programmation générique aux macros : avec les macros, on n'a pas de validation des types alors qu'avec les templates, on va pouvoir vérifier toutes les conditions qui peuvent l'être à la compilation (d'ailleurs, on va publier dans les semaines à venir des articles sur Boost.Proto, permettant de définir et valider des grammaires à la compilation).

  4. #4
    Membre éclairé Avatar de seeme
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    430
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 430
    Points : 791
    Points
    791
    Par défaut
    Les structures qui sont créées par les macros sont templatées

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 113
    Points : 32 960
    Points
    32 960
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par seeme Voir le message
    Les structures qui sont créées par les macros sont templatées
    Que veux-tu dire par là ?

    Pour ma part oui j'utilise des macros, quand nécessaire, pour leur fonction première : remplacer au parsing du preprocessor.
    90% des macros que j'écris le sont pour ne pas avoir à recopier un code redondant style succession de if. Evitant par la même occasion des erreurs d'innatention dûes aux c/c.
    Et pour pouvoir identifier les différentes cibles et/ou du code spécifique selon la cible. Typiquement quand la cible est Debug, ajouter des traces et diverses informations pour le debug justement .
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #6
    Membre éclairé Avatar de seeme
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    430
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 430
    Points : 791
    Points
    791
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Que veux-tu dire par là ?

    Pour ma part oui j'utilise des macros, quand nécessaire, pour leur fonction première : remplacer au parsing du preprocessor.
    90% des macros que j'écris le sont pour ne pas avoir à recopier un code redondant style succession de if. Evitant par la même occasion des erreurs d'innatention dûes aux c/c.
    Et pour pouvoir identifier les différentes cibles et/ou du code spécifique selon la cible. Typiquement quand la cible est Debug, ajouter des traces et diverses informations pour le debug justement .
    Les macros cachent la création de structures templatées qui représentent les données chargées du xml.

  7. #7
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 156
    Points
    3 156
    Par défaut
    Citation Envoyé par seeme Voir le message
    Citation Envoyé par Bousk Voir le message
    Que veux-tu dire par là ?

    Pour ma part oui j'utilise des macros, quand nécessaire, pour leur fonction première : remplacer au parsing du preprocessor.
    90% des macros que j'écris le sont pour ne pas avoir à recopier un code redondant style succession de if. Evitant par la même occasion des erreurs d'innatention dûes aux c/c.
    Et pour pouvoir identifier les différentes cibles et/ou du code spécifique selon la cible. Typiquement quand la cible est Debug, ajouter des traces et diverses informations pour le debug justement .
    Les macros cachent la création de structures templatées qui représentent les données chargées du xml.
    Qu'est ce que c'est que ce dialogue de sourd ? Qu'est ce que XML vient faire là dedans
    Find me on github

  8. #8
    Membre éclairé Avatar de seeme
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    430
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 430
    Points : 791
    Points
    791
    Par défaut
    Citation Envoyé par jblecanard Voir le message
    Qu'est ce que c'est que ce dialogue de sourd ? Qu'est ce que XML vient faire là dedans
    Ca vient de mon premier post en fait

  9. #9
    Membre régulier
    Inscrit en
    Juin 2008
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 140
    Points : 103
    Points
    103
    Par défaut
    Pour bien comprendre un des exemples :
    II-C-1. Code de débogage
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void f()
    {
        #ifdef MY_DEBUG
        cerr << "some trace logging" << endl;
        #endif
     
        // ... le reste de f() va ici...
    }
    le code entre le #ifdef et #endif sera-t-il compilé si MY_DEBUG est différent de 1 ? Si oui, comment sera-t-il exécuté ensuite (à l’exécution) ?

  10. #10
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Citation Envoyé par MicBeastKiller Voir le message
    Pour bien comprendre un des exemples :
    II-C-1. Code de débogage
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void f()
    {
        #ifdef MY_DEBUG
        cerr << "some trace logging" << endl;
        #endif
     
        // ... le reste de f() va ici...
    }
    le code entre le #ifdef et #endif sera-t-il compilé si MY_DEBUG est différent de 1 ? Si oui, comment sera-t-il exécuté ensuite (à l’exécution) ?
    La compilation se passe en 2 temps : le préprocesseur passe en premier et interprète les macros pour fournir le code C++ sans macro ; puis le compilateur fait son boulot.
    Donc cela revient à compiler le code suivant dans le premier cas :
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void f()
    {
        // ... le reste de f() va ici...
    }
    et le code entre les #ifdef n'apparaît pas dans le binaire
    Et dans le second cas :
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void f()
    {
        cerr << "some trace logging" << endl;
        // ... le reste de f() va ici...
    }
    et le code entre les #ifdef apparaît dans le binaire

    Attention : #ifdef = "if define". Ce n'est pas pareil que "#if MY_DEBUG != 1". A partir du moment où MY_DEBUG existe, c'est bon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #define MY_DEBUG
    #define MY_DEBUG 1
    #define MY_DEBUG ou n'importe quoi ici
    Pour rappel, pour "supprimer" un define, il faut utiliser #undef

  11. #11
    Membre régulier
    Inscrit en
    Juin 2008
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 140
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    La compilation se passe en 2 temps : le préprocesseur passe en premier et interprète les macros pour fournir le code C++ sans macro ; puis le compilateur fait son boulot.
    Donc cela revient à compiler le code suivant dans le premier cas :
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void f()
    {
        // ... le reste de f() va ici...
    }
    et le code entre les #ifdef n'apparaît pas dans le binaire
    Et dans le second cas :
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void f()
    {
        cerr << "some trace logging" << endl;
        // ... le reste de f() va ici...
    }
    et le code entre les #ifdef apparaît dans le binaire

    Attention : #ifdef = "if define". Ce n'est pas pareil que "#if MY_DEBUG != 1". A partir du moment où MY_DEBUG existe, c'est bon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #define MY_DEBUG
    #define MY_DEBUG 1
    #define MY_DEBUG ou n'importe quoi ici
    Pour rappel, pour "supprimer" un define, il faut utiliser #undef
    Merci pour le rappel final.

Discussions similaires

  1. Les "Guru of the week" en français
    Par gbdivers dans le forum C++
    Réponses: 16
    Dernier message: 03/08/2012, 16h53
  2. Réponses: 8
    Dernier message: 25/06/2012, 23h34
  3. Guru of the Week 104
    Par gbdivers dans le forum C++
    Réponses: 15
    Dernier message: 25/04/2012, 15h27

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