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 :

une question de style ?


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    32
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 32
    Par défaut une question de style ?
    Bonjour,

    une personne (qui n'est plus dans nos locaux, je ne peux donc pas lui poser la question) a modifié une macro mais je ne saisis pas l'intérêt de cette modification.

    Je m'explique, la macro était la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #define DESACTIVE_UNTRUC (flag) {flag &= 0xFC;}  // mise à 0 des bits 0 et 1
    Elle a été modifiée ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #define DESACTIVE_UNTRUC (flag) do {flag &= 0xFC;} while(0)
    Quel est l'intérêt du rajout du do while(0) ?

    Merci

  2. #2
    Membre très actif

    Inscrit en
    Juillet 2008
    Messages
    186
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 186
    Par défaut
    Bonjour,

    L'ajout du do {} while (0) permet d'écrire le code suivant, comme si la macro était un appel de fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (mon_test)
        DESACTIVE_UNTRUC(toto);
    else
        DESACTIVE_UNTRUC(tata);
    Ce que la version sans le do-while ne permet pas. Elle génère une erreur de compilation sur le else à cause du point virgule qui précède.

    Didier

  3. #3
    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
    Manque de pot, sous Visual en mode parano, ça génère un warning "condition constante", et il n'y a aucun moyen d'éviter cela sans désactiver complètement le warning en question.
    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.

  4. #4
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    C'est que chez Microsoft ils ont les idées courtes

    Le coups du do {} while (0) est très courant, et c'est la façon la plus sûre (même si elle n'est pas parfaite) d'écrire une macro de plus d'une instruction.

  5. #5
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Manque de pot, sous Visual en mode parano, ça génère un warning "condition constante", et il n'y a aucun moyen d'éviter cela sans désactiver complètement le warning en question.
    Quels abrutis...

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    32
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 32
    Par défaut
    Le coup du if ça ne s'invente pas ...

    Merci pour la réponse.

    Par contre, je ne suis jamais tombé sur le cas car personnellement je préfère mettre les accolades sur mon if même s'il n'y a qu'une seule instruction.
    En effet, régulièrement je me fait avoir en voulant rajouter une log dans un if en oubliant de rajouter les accolades.

    Mais le do while(), je retiens ...

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 485
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 485
    Par défaut
    Je vais peut-être dire une ânerie mais il me semble que rien, dans la norme, n'impose d'associer un bloc entre accolades à un mot-clé ou une condition quelquonque ...

    Pour moi, les accolades servent à faire ce à quoi elles servent dans le langage courant : regrouper leur contenu en une seule unité grammaticale, et il semblerait que ce soit défini comme tel dans la section 6.8 de C99 :

    3 A block allows a set of declarations and statements to be grouped into one syntactic unit. The initializers of objects that have automatic storage duration, and the variable length array declarators of ordinary identifiers with block scope, are evaluated and the values are stored in the objects (including storing an indeterminate value in objects without an initializer) each time the declaration is reached in the order of execution, as if it were a statement, and within each declaration in the order that declarators appear.
    La déclaration d'un bloc « seul » au milieu d'une fonction compile au moins avec gcc et le compilateur des Solaris, et j'ai vu le précompilateur de l'Embedded C/SQL de Sybase générer du code se servant de cela, aussi.

    On peut même y déclarer de nouvelles variables locales. Évidemment, ce n'est pas propre parce qu'en général, si on a besoin d'y recourir, c'est qu'on s'est mis dans une impasse, mais dans le cas d'une macro, ça prend tout son sens ...

  8. #8
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Oui bien sûr, tu peux créer un bloc sans l'associer à quoi que ce soit. Mais le problème si tu fais ça, c'est que tu ne peux pas utiliser la macro ainsi définie dans un if/else sans accolades, parce que si tu fais ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (...)
        MACRO(...);
    else
       ...
    Alors après le passage du préprocesseur ça donne ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (...)
        { ... };
    else
       ...
    Note bien le point virgule avant le else... Ca donne une erreur de syntaxe, puisque le else n'est plus associé au if. En effet tu as un if avec accolades, suivit d'une instruction vide qui dissocie le else du if.

    Avec le do { ... } while (0), ça donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (...)
        do { ... } while (0);
    else
        ...
    Ce qui est parfaitement valide.

  9. #9
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par barbouille Voir le message
    Par contre, je ne suis jamais tombé sur le cas car personnellement je préfère mettre les accolades sur mon if même s'il n'y a qu'une seule instruction.
    En effet, régulièrement je me fait avoir en voulant rajouter une log dans un if en oubliant de rajouter les accolades.
    Oui, c'est une bonne pratique que je recommande aussi, mais tout le monde n'est pas aussi attentif, et quand on écrit une macro 'publique', nul ne sait comment elle sera utilisée. On se doit donc d'être irréprochable et de prévoir tous les cas.

    Nota dans certains cas, l'opérateur ',' suffit.
    Mais le do while(), je retiens ...
    Mais pour revenir à l'exemple initial, comme il n'y a qu'une instruction, ceci suffit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define DESACTIVE_UNTRUC(flag) flag &= 0xFC
    Attention, pas d'espace avant '(' dans une définition de macro

  10. #10
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par barbouille Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #define DESACTIVE_UNTRUC (flag) do {flag &= 0xFC;} while(0)
    Quel est l'intérêt du rajout du do while(0) ?
    Déjà, c'est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define DESACTIVE_UNTRUC(flag) do {flag &= 0xFC;} while(0)
    ensuite :

    http://www.levenez.com/lang/c/faq/fclc013.html#q_16

    mais ici, il n'y a qu'une instruction...

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    32
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 32
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Déjà, c'est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define DESACTIVE_UNTRUC(flag) do {flag &= 0xFC;} while(0)
    ensuite :

    http://www.levenez.com/lang/c/faq/fclc013.html#q_16

    mais ici, il n'y a qu'une instruction...
    Vi bon !!! J'm'a effectivement trompé en recopiant ...

    et pour le lien.

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

Discussions similaires

  1. Une question de style
    Par sethlegoauld dans le forum Ext JS / Sencha
    Réponses: 1
    Dernier message: 05/08/2010, 22h51
  2. Encore une question sur malloc
    Par IG88 dans le forum C
    Réponses: 5
    Dernier message: 23/06/2004, 15h35
  3. [.NET] Une question technique a propos du mode asynchrone
    Par nicknolt dans le forum Général Dotnet
    Réponses: 4
    Dernier message: 08/06/2004, 10h07
  4. Une question à propos des thread
    Par tscoops dans le forum C++Builder
    Réponses: 4
    Dernier message: 07/11/2003, 14h03
  5. Rattacher une feuille de style a un XML existant
    Par aour dans le forum XML/XSL et SOAP
    Réponses: 5
    Dernier message: 08/10/2002, 22h07

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