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 :

switch -> default -> break ?


Sujet :

Langage C++

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut switch -> default -> break ?
    Hello,

    L'outil d'analyse de code d'Eclipse CDT râle quand dans un switch, je ne mets pas de break dans la clause default.

    Que dit la norme ?

  2. #2
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Salut.
    Vu qu'on peut ne pas en mettre dans les case, ce serait étonnait qu'il soit obligatoire de le faire pour default...

    Et puis il me semble qu'elle doit être mise à la fin (enfin je veux dire, ça n'a pas de sens de mettre des case après, si ?), alors il faudra qu'on m'explique l'intérêt de vouloir couper une structure de contrôle à la toute dernière instruction...

    Ton outil d'analyse ne te demanderait pas de mettre des continue à la fin des boucles, par hasard ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while (...) {
        (...)
        continue;
    }

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Citation Envoyé par Steph_ng8 Voir le message
    Vu qu'on peut ne pas en mettre dans les case, ce serait étonnait qu'il soit obligatoire de le faire pour default...
    Attention, il me génère un warning, pas une erreur. Et je pense qu'il le ferait également dans le cas d'un case, sauf s'il est vide.

    Citation Envoyé par Steph_ng8 Voir le message
    Et puis il me semble qu'elle doit être mise à la fin (enfin je veux dire, ça n'a pas de sens de mettre des case après, si ?),
    C'est un usage, logique, mais y est-on vraiment obligé ?
    On peut considérer que les case seront utilisés dans des cas exceptionnels, que dans la grande majorité des cas, on se retrouvera dans le default, et qu'alors, cela aurait un sens de le mettre au début.

    Pour savoir ce que default doit traiter, doit-on déjà être passé par les case ?

  4. #4
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Citation Envoyé par oodini Voir le message
    Pour savoir ce que default doit traiter, doit-on déjà être passé par les case ?
    D'après ce que j'ai compris, le résultat de l'expression du switch est comparé successivement avec la valeur de chaque case, dans l'ordre dans lequel ils sont écrits, jusqu'à arriver à une correspondance, la clause default, ou la fin du switch ... case.
    C'est pour ça que je pense que ça n'a pas de sens de mettre des case après un default.
    Ce serait comme écrire des instructions après un return (non conditionnel)...

    Après, je peux me tromper.
    Si tous les case sont passés en revue avant de passer à la clause default, alors la position de celle-ci n'a a priori pas vraiment d'importance...

  5. #5
    Membre Expert
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Par défaut
    le parcours du switch n'est pas lineaire mais en O(1), l'ordre importe peu.

    http://codepad.org/95lH5ojF

    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
     
    #include <iostream>
    using namespace std;
     
    int main()
    {
      int i(4);
     
      switch(i)
      {
        case 1 : cout << "coin 1"; break;
        default: cout << "coin d"; break;
        case 0 : cout << "coin 0"; break;
      }
    }

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    OK, j'ai donc ma réponse.

    Merci !

  7. #7
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par Steph_ng8 Voir le message
    Et puis il me semble qu'elle doit être mise à la fin (enfin je veux dire, ça n'a pas de sens de mettre des case après, si ?), alors il faudra qu'on m'explique l'intérêt de vouloir couper une structure de contrôle à la toute dernière instruction...
    J'ai vu du code qui faisait systématiquement ça : le default au début, puis les case ensuite. C'était souvent parce que le cas par défaut était le(s) cas OK alors que les case traitaient des cas d'erreur. C'est pas forcément ce qu'il y a de plus clair mais ça existe.

    L'absence de break sur le dernier cas (que ce soit un default ou un case) est plus une erreur d'esthétique. Note que les règles de codage stipulent de mettre systématiquement un default et de mettre systématiquement un break. L'absence devant être justifiée dans le code pour montrer qu'il s'agit bien d'un cas souhaité et non d'un oubli.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 638
    Par défaut
    Salut,

    Il ne faut pas oublier, non plus, que, en cas d'absence de break, plusieurs cas peuvent etre exécutés successivement...

    Cela peut etre souhaité (bien que non (ou du moins pas forcément) souhaitable) si les actions à effectuer dans un cas donné sont un "subset" du cas précédent, mais cela peut surtout apporter quelques soucis majeurs, dus, essentiellement à ce comportement particulier
    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
    int main()
    {
        int i(1);
        switch (i)
        {
            case 1:
                std::cout<<"cas 1"<<std::endl;
            case 2:
                std::cout<<"cas 2"<<std::endl;
                break;
            case 3: 
                std::cout<<"cas 3"<<std::endl;
                break;
            default :
               std::cout<<"cas par défaut"<<std::endl;
        }
        return 0;
    }
    Le dernier cas envisagé (default dans le cas présent ) ne posera pas de problème... tant que l'on ne décidera pas de rajouter une valeur en dessus

    cet avertissement fait sans doute preuve d'un excès de prévoyance, mais j'ai tendance à estimer que l'on n'est jamais assez paranoïaque dans une revue de code
    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

  9. #9
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    L'absence de break sur le dernier cas (que ce soit un default ou un case) est plus une erreur d'esthétique.
    Ah ?
    Personnellement, je trouve que c'est plus esthétique de ne pas le mettre...
    À moins que ce soit ça l'erreur ?

    Citation Envoyé par 3DArchi Voir le message
    Note que les règles de codage stipulent de mettre systématiquement un default et de mettre systématiquement un break.
    Même si ça n'a pas de sens de mettre une clause « par défaut » ?
    Je veux dire s'il y a un cas pour toutes les valeurs possibles de l'expression (énumération, caractère dont on sait que c'est un chiffre, etc.) ?

    Citation Envoyé par 3DArchi Voir le message
    L'absence devant être justifiée dans le code pour montrer qu'il s'agit bien d'un cas souhaité et non d'un oubli.
    L'absence du default ou du break ?

  10. #10
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par Steph_ng8 Voir le message
    Ah ?
    Personnellement, je trouve que c'est plus esthétique de ne pas le mettre...
    À moins que ce soit ça l'erreur ?
    Ben, le comportement ne changera pas, mais perso, je serais systématiquement surpris quand je verrai le dernier default/case du switch sans break.
    Citation Envoyé par Steph_ng8 Voir le message
    Même si ça n'a pas de sens de mettre une clause « par défaut » ?
    Je veux dire s'il y a un cas pour toutes les valeurs possibles de l'expression (énumération, caractère dont on sait que c'est un chiffre, etc.) ?
    Oui. C'est vrai que c'est parfois absurde car la clause default ne sera jamais atteinte. Ca donne un côté uniforme au code. Mais c'est probablement un reste de la programmation défensive.
    Citation Envoyé par Steph_ng8 Voir le message
    L'absence du default ou du break ?
    L'absence du break. Mais d'une façon général, toute les non respects des règles. C'est tout simplement pour montrer que ce n'est pas une erreur de codage mais que c'est bien voulu.

  11. #11
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Ok.
    Je ne connaissais pas ces deux règles de codage.

    Lorsque j'ai appris la structure switch ... case ..., j'avais retenu que l'on ne met que les cas qui nous intéressent ; et que par conséquent, on ne met de met de clause default que lorsque c'est nécessaire.
    Par contre, pour l'absence de break pour le dernier cas, c'est juste moi qui trouvais inutile de mettre une instruction qui, finalement, ne fait rien...

    Dorénavant, je respecterai ces règles à la lettre.
    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
    enum e_enum {UN, DEUX, TROIS};
     
    e_enum x = (...);
    switch (x) {
        case UN:
            (...)
            break;
     
        case DEUX:
            (...)
            break;
     
        case TROIS:
            (...)
            break;
     
        default:
            throw std::runtime_error("Valeur illégale pour une énumération !!!");
            // Il faut mettre un « break » ici aussi ?
    }

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 638
    Par défaut
    Citation Envoyé par Steph_ng8 Voir le message
    Ok.
    Je ne connaissais pas ces deux règles de codage.

    Lorsque j'ai appris la structure switch ... case ..., j'avais retenu que l'on ne met que les cas qui nous intéressent ; et que par conséquent, on ne met de met de clause default que lorsque c'est nécessaire.
    Celui qui t'a appris cela est... hummm, je vais rester gentil et poli

    La meilleure preuve, c'est que, si tu règle le compilateur pour qu'il soit "paranoïaque", il t'enverra un avertissement si tous les cas d'une énumérations ne sont pas pris en compte, meme si tu sais que seules deux ou trois valeurs énumérées risquent d'être utilisés
    Par contre, pour l'absence de break pour le dernier cas, c'est juste moi qui trouvais inutile de mettre une instruction qui, finalement, ne fait rien...

    Dorénavant, je respecterai ces règles à la lettre.
    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
    enum e_enum {UN, DEUX, TROIS};
     
    e_enum x = (...);
    switch (x) {
        case UN:
            (...)
            break;
     
        case DEUX:
            (...)
            break;
     
        case TROIS:
            (...)
            break;
     
        default:
            throw std::runtime_error("Valeur illégale pour une énumération !!!");
            // Il faut mettre un « break » ici aussi ?
    }
    Cela ne mange, en tout cas, pas de pain

    L'avantage, c'est que si tu rajoute QUATRE et que, par distraction ou que sais-je, tu mets cette valeur après default, tu es sur qu'il n'y aura pas de problème (comprends : si d'aventure, default fait autre chose que lancer une exception )
    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

  13. #13
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Celui qui t'a appris cela est... hummm, je vais rester gentil et poli
    Hey !
    J'ai dit : « j'avais retenu » !
    Je ne crois pas que la personne en question l'a explicitement dit, c'est juste ce qui m'est resté.

    Citation Envoyé par Bernard Werber
    Tentative
    Entre
    Ce que je pense
    Ce que je veux dire
    Ce que je crois dire
    Ce que je dis
    Ce que vous avez envie d'entendre
    Ce que vous croyez entendre
    Ce que vous entendez
    Ce que vous avez envie de comprendre
    Ce que vous croyez comprendre
    Ce que vous comprenez
    Il y a dix possibilités qu'on ait des difficultés à communiquer.
    Mais essayons quand même...
    L'encyclopédie du savoir relatif et absolu
    © Éditions Albin Michel S.A., 2000.


    Citation Envoyé par koala01 Voir le message
    Cela ne mange, en tout cas, pas de pain

    L'avantage, c'est que si tu rajoute QUATRE et que, par distraction ou que sais-je, tu mets cette valeur après default, tu es sur qu'il n'y aura pas de problème (comprends : si d'aventure, default fait autre chose que lancer une exception )
    Ok.

  14. #14
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Citation Envoyé par Steph_ng8 Voir le message
    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
    enum e_enum {UN, DEUX, TROIS};
     
    e_enum x = (...);
    switch (x) {
        case UN:
            (...)
            break;
     
        case DEUX:
            (...)
            break;
     
        case TROIS:
            (...)
            break;
     
        default:
            throw std::runtime_error("Valeur illégale pour une énumération !!!");
            // Il faut mettre un « break » ici aussi ?
    }
    Dans un cas comme ça, cela s'apparenterait probablement plus à une violation de contrat. Plutôt que de lever une exception, je ferais un assert
    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
    enum e_enum {UN, DEUX, TROIS};
     
    e_enum x = (...);
    switch (x) {
        case UN:
            (...)
            break;
     
        case DEUX:
            (...)
            break;
     
        case TROIS:
            (...)
            break;
     
        default:
            assert(false);
            break;
    }
    Ceci dit :
    Citation Envoyé par Steph_ng8 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        default:
            throw std::runtime_error("Valeur illégale pour une énumération !!!");
            // Il faut mettre un « break » ici aussi ?
    }
    c'est un cas particulier où compilateur et outils de vérification de code peuvent râler pour indiquer un code non atteignable si tu mets un break. C'est le genre de cas très particulier pour indiquer qu'on ne mets pas de break pour cette raison :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        default:
            throw std::runtime_error("Valeur illégale pour une énumération !!!");
            // Rule XX not followed : break unused since code is unreachable due to exception raising
    }
    ce qui pourrait être aussi être le cas dans des case
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    switch(x)
        case E_1:
             return do_something();
            // Rule XX not followed  : break unused since code is unreachable due to return statement
        case E_2:
    ...
    }

  15. #15
    Membre Expert
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Par défaut
    les case sans break servent surtout a implanter un Duff's Device

  16. #16
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Si j'ai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    case 0 :
    case 1 :
    case 2 :
        instructions;
        break;
    le compilateur en râle pas, mais si j'ai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    case 0 :
    case 1 :
        instructions;
    case 2 :
        instructions;
        break;
    le compilateur râle parce que le case 1 n'a pas de break, alors que c'est voulu.

    Peut-on par exemple mettre un continue pour indiquer que c'est voulu ?
    Cet ajout est-il neutre ?

Discussions similaires

  1. switch/case & default
    Par Invité(e) dans le forum Général Python
    Réponses: 10
    Dernier message: 13/11/2009, 11h57
  2. case switch sans break
    Par virtuadrack dans le forum C
    Réponses: 3
    Dernier message: 18/04/2007, 08h13
  3. break de switch conditionnel
    Par Gruik dans le forum C
    Réponses: 26
    Dernier message: 10/02/2007, 16h30
  4. Position de default et case dans un switch
    Par Glutinus dans le forum C
    Réponses: 16
    Dernier message: 11/09/2006, 22h17

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