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

Langage C++ Discussion :

[best practices] sortir d'une boucle


Sujet :

Langage C++

  1. #1
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut [best practices] sortir d'une boucle
    Bonjour,

    dans le code sur lequel je travaille en ce moment, je trouve beaucoup de boucles écrites dans le style:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    bool stop_condition = false;
    for(int i=0;i<10;++i)
    {
       stop_condition = do_something();
       if (stop_condition==true)
          break;
    }
    Alors que j'ai toujours pensé qu'il serait préférable de procéder comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    bool stop_condition = false;
    int i=0;
    while ( stop_condition==false && i<10 )
    {
       stop_condition = do_something();
    }
    Seulement en y réfléchissant, j'ai du mal à argumenter sur les raisons qui font que le 2eme code est préférable au 1er. Selon vous, pour quelles raisons devons-nous préférer le 2eme exemple?
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  2. #2
    Membre chevronné Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Points : 2 160
    Points
    2 160
    Par défaut
    Si on met de côté l'utilisation de find_if.

    J'ai un préférence pour :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (auto const & e : v)
    {
        if (do_something(e)) { break; }
    }
    Même si "détourne" l'utilisation d'une boucle for (nombre d'itérations connus). Je trouve cette solution pratique car elle limite le nombre et la portée des variables et est (très) lisible (je "triche" avec l'utilisation de C++11).
    break et d'autres mots clefs de ce genre sont des éléments du langage qui existent, il sont puissants (et donc dangereux si on en abuse) mais peuvent et améliorer la lisibilité dans certains cas; il est dommage de s'en priver.

  3. #3
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 190
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 190
    Points : 17 146
    Points
    17 146
    Par défaut
    Pour moi, ca dépend de la nécessité de se souvenir de la raison de l'arret.
    Si on s'en moque, le for-break me semble assez correct, avec la subtilité de préférer retourner true pour les succès
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for(int i=0;i<10;++i) {
       if (!do_something()) break;
    }
    Si on veut s'en souvenir, je me demande bien pourquoi… vu qu'on a le RAII.

    Les cas courants de boucle interrompues sont les détections (et comptage), et les erreurs.
    Pour compter, on a effectivement aussi les std::find et std::find_if.

    Abuser de RAII permet de tout nettoyer en partant, et donc permet les sorties rapides:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for(int i=0;i<10;++i) {
       if (!do_something()) return false;
    }
    for(int i=0;i<10;++i) {
       if (!do_something()) throw std::out_of_range("machin");
    }
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  4. #4
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Points : 1 475
    Points
    1 475
    Par défaut
    Citation Envoyé par leternel Voir le message
    Si on veut s'en souvenir, je me demande bien pourquoi… vu qu'on a le RAII.
    S'il s'agit d'un cas d'erreur, ça peut le faire, mais si ça fait partie de l'algorithme, je trouve préférable d'écrire les conditions de fin d'itération au même endroit. Il y a un compromis à trouver avec la lisibilité de l'instruction de boucle, effectivement, mais faire une boucle for classique dont la vraie condition de fin d'itération est ailleurs c'est vraiment savonner la planche au(x) pauvre(s) types qui devront relire plus-tard (voir à soi-même...la mémoire de ce genre de truc s’estompe vite avec le temps, et honnêtement il y a plus utile à faire de sa mémoire...)

  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Si la condition est effectivement à la toute fin du bloc, je ferais plutôt :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (int i=0; i<10 && !stop_condition; ++i)
    {
        ...
    }

  6. #6
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    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 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Autant la présence de break dans des boucles while ne me gène pas vraiment, même si je préfère avoir si possible toutes les conditions de sorties de boucle en argument (ça se dit ? ) du while, c'est en général un peu plus lisible.

    Autant pour le for, je m'interdit tout break.
    En effet, pour moi le for, c'est un nombre d'itérations connu lors de l'entrée dans la boucle : On parcourt X éléments d'un conteneur ou on fait X tours.

    Si le nombre d'itération à faire change dans la boucle ( break, condition déterminée par le retour d'une fonction, etc. ), je préfère utiliser un while.
    Je trouve que c'est plus clair pour celui qui lit :
    for = je te dit d'avance combien de tours on va faire
    while = le nombre de tour peut être variable.

    Après, il est vrai qu'avec le for du C++11, je me suis déjà autorisé un break ( un peu par flemme, je le reconnais ) mais je considère alors que c'est un cas d'erreur, un peu comme si je lançais une exception.

  7. #7
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Je m'interdis personnellement d'interdire de faire du SEME et assimilé (break, return, continue).
    On n'est plus en C, pas besoin de se rediriger à la fin d'un bloc pour y nettoyer des ressources. Le RAII est là pour ça.

    r0d, si tu ne trouves pas argument en faveur du flag dans la boucle, c'est justement parce qu'il n'y en a aucun de valide ... en C++.

    Bref, mon opinion sur le sujet, on la retrouve à ces divers endroits:
    - http://www.developpez.net/forums/d23...iveau-methode/
    - http://www.developpez.net/forums/d37...ondition-else/
    - http://www.developpez.net/forums/d91...-continue-cpp/
    - http://herbsutter.com/2013/05/13/got...orary-objects/
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  8. #8
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Merci à tous pour votre point de vue.

    <HS>
    punaise, quand je lis cette discussion, je me rend compte que je viens de loin... je débutais en c++ à l'époque et je ne faisais même pas la différence entre le C et le C++
    </HS>
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  9. #9
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Un jour, tes souvenirs du C seront fumeux, et tu pesteras contre Visual avant de comprendre qu'il faut déclarer toutes tes variables au début du programme.

  10. #10
    Membre chevronné Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 044
    Points : 2 239
    Points
    2 239
    Par défaut
    Bonjour,

    Entre ces deux codes, il y a de forte chance pour que le compilateur te donne le même assembleur une fois compilé. Les deux boucles sont assez simple donc facilement optimisable par le compilateur. Mais ce n'est pas dit pour une boucle plus complexe.
    A voir l'assembleur final optimisé, mais je dirais kifkif.

    Sinon pour ce qui est de la lecture de code, je privilégierais la visibilité des conditions de sortie, donc toute au début de la boucle que ça soit for ou while et non pas dans le corps de la boucle.

    Cordialement,
    Homer J. Simpson


  11. #11
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    A vrai dire, je n'ai jamais écrit un break ou un continue dans une boucle en C++ (à moins, bien sur, qu'il n'y ait un switch... case dans la boucle )

    Par contre, j'ai déjà souvent écrit un return, qu'il renvoie une valeur ou non (généralement, il en renvoie une vu que cette valeur sera utile ailleurs )

    De manière générale, j'essaye généralement d'utiliser la boucle qui correspond le mieux à ce que je veux faire, c'est à dire:

    La boucle "pour" si je dois travailler sur un "range" (que ce soit d'index ou d'itérateurs), la boucle "while" (voir do while) si je recherche une information particulière.

    Je suis particulièrement critique, par contre, au fait de placer deux (ou plus) condition d'arrêt dans une boucle pour comme le propose oodini
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  12. #12
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Je suis particulièrement critique, par contre, au fait de placer deux (ou plus) condition d'arrêt dans une boucle pour comme le propose oodini
    Subjectivité assumée, ou phase d'argumentation en préparation ?

  13. #13
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Mon avis sur les break/continue: http://programmers.stackexchange.com...es/58253#58253

    When used at the start of a block, as first checks made, they act like preconditions, so it's good.

    When used in the middle of the block, with some code around, they act like hidden traps, so it's bad.
    Perso je prefere me permettre d'agencer le code au cas par cas de maniere lisible plutot que de suivre des dogmes.

  14. #14
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par oodini Voir le message
    Subjectivité assumée, ou phase d'argumentation en préparation ?
    Subjectivité assumée

    Autant je trouves "cohérent" d'avoir, par exemple, plusieurs conditions de sorties avec une boucle "while" (while (condition1 && condition2) ) autant j'estime que la seule condition de sortie d'une boucle pour devrait etre... la sortie de la plage de valeurs envisagées.

    C'est d'ailleurs pour cela que je préférerai utiliser une boucle "while" (voire do while) pour créer une boucle (considérée comme) infinie, plutôt qu'une boucle "pour"
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. Sortir d'une boucle for
    Par gids01 dans le forum Langage
    Réponses: 9
    Dernier message: 14/11/2006, 15h06
  2. Sortir d'une boucle de parcour d'un Recordset
    Par Mariboo dans le forum IHM
    Réponses: 2
    Dernier message: 12/06/2006, 18h07
  3. Sortir d'une boucle en fonction d'une durée
    Par BECHE dans le forum Langage
    Réponses: 8
    Dernier message: 30/11/2005, 11h08
  4. [DEBUTANT] sortir d'une boucle avec un touche particulière
    Par thibouille dans le forum Débuter
    Réponses: 4
    Dernier message: 25/10/2005, 06h44
  5. SORTIR D'UNE BOUCLE
    Par chekibperl dans le forum Langage
    Réponses: 2
    Dernier message: 22/10/2005, 12h48

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