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 :

Return à l'intérieur d'une boucle for -> warning


Sujet :

C++

  1. #21
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2011
    Messages : 13
    Par défaut
    Tu trouvera une partie de la réponse dans la FAQ
    http://cpp.developpez.com/faq/cpp/?page=references

    Une référence ne pouvant pas être nulle, si la signature de ta fonction renvoie une référence elle annonce clairement la couleur: elle renverra forcement un objet valide. Ce qui correspond a la pre-condition.

  2. #22
    Membre confirmé
    Inscrit en
    Juin 2008
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 140
    Par défaut
    Citation Envoyé par Gymble Voir le message
    Tu trouvera une partie de la réponse dans la FAQ
    http://cpp.developpez.com/faq/cpp/?page=references

    Une référence ne pouvant pas être nulle, si la signature de ta fonction renvoie une référence elle annonce clairement la couleur: elle renverra forcement un objet valide. Ce qui correspond a la pre-condition.
    Merci.

    Néanmoins, me reste à implémenter cela avec le problème de l'itérateur de recherche : que dois-je renvoyer alors ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Element& searchElement( std::vector< Element * >& aVectorOfElements , std::string const anId )
    {
    	std::vector< Element  * >::iterator anIter = aVectorOfElements.begin();
    	for( ; anIter != aVectorOfElements.end() ; ++anIter )
    	{
    		if( (*anIter)->m_id == anId )
    		{
    			return( *anIter );
    		}
    	}
    }
    le passage provoque une erreur de compilation (que je comprends bien) mais je ne vois pas trop quoi mettre ...

  3. #23
    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
    anIter est une sorte de pointeur (pour faire simple) vers un élément de ton vecteur.

    *anIter est donc un élément de ton vecteur, c'est à dire un Element *.
    Si tu veux un élément il faut utiliser **anIter

  4. #24
    Membre confirmé
    Inscrit en
    Juin 2008
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 140
    Par défaut
    Citation Envoyé par Neckara Voir le message
    anIter est une sorte de pointeur (pour faire simple) vers un élément de ton vecteur.

    *anIter est donc un élément de ton vecteur, c'est à dire un Element *.
    Si tu veux un élément il faut utiliser **anIter
    Après coup, c'est ce que j'ai compris oui .
    Néanmoins, cela ne règle pas le problème de warning initial

  5. #25
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2011
    Messages : 13
    Par défaut
    Une exception après le for règle le problème du warning.

    Edit : Comme cela a été dis plus haut, par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Element& searchElement( std::vector< Element * >& aVectorOfElements , std::string const &anId )
    {
    	std::vector< Element  * >::iterator anIter = aVectorOfElements.begin();
    	for( ; anIter != aVectorOfElements.end() ; ++anIter )
    		if( (*anIter)->m_id == anId )
    			return( **anIter );
     
    	throw std::logic_error("Cette ligne ne devrait pas être atteinte");
    }

  6. #26
    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
    Il faut que tu jette une exception à la fin de ta fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Type exception;
    throw(exception);
     
    exemple :
    throw("Erreur, précondition : 'l'élément doit être dans l'ensemble des Élément' non respecté!"); //on jette un char *

  7. #27
    Membre confirmé
    Inscrit en
    Juin 2008
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 140
    Par défaut
    Merci pour vos réponses. Je vais donc regarder comment implémenter des exceptions.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    En fait, généralement, on va créer un hiérarchie de classes correspondant aux différentes exceptions qui pourront être lancées, car la réaction lorsqu'elle est attrapée peut varier en fonction de ce qui l'a provoquer...

    Tu pourrais très bien avoir une classe Exception proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Exception : public std::runitme_error  // runtime_error est l'exception standard pour dire qu'une erreur est survenue à l'exécution
    {
        public:
            Exception(std::string const & what, std::string const & more):
            std::runtime_error(what), more_(more){}
            /* on peut donner encore d'avantage d'information pour préciser
             * le contexte, si on décide d'afficher l'erreur)
             */
           std::string const & more() const{return more_;}
        private:
            std::string more_;
    };
    Pour un élément non trouvé, la classe dérivée pourrait ressembler à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class ElementNotFound : public Exception
    {
        static std::string stringizer(std::string id)
        {
            std::string temp("L'element ");
            temp.append(id)
                .append("n'a pas ete trouve");
            return temp;
        }
        public:
            ElementNotFound(std::string const & id):Exception("ElementNotFound",stringizer(id)){}
    };
    et le code d'appel de searchElement serait proche de
    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
    void foo(/* ... */)
    {
        try
        {
            /* ... */
           Element & elem = searchElement(tab, id);
        }
        /* l'exception qui nous intéresse */
        catch(ElementNotFound &)
        {
            // ce qu'il faut faire
        }
        /* au cas où la logique aurait fait lancer une autre exception à nous */
        catch(Exception & )
        {
           // ce qu'il faut faire
        }
        /* pour les exceptions runtime éventuellement lancée par STL */
        catch(std::runtime_exception &)
        {
            // ce qu'il faut faire
        }
        /* pour toutes les autres exceptions */
        catch(... )
        {
            std::cout<<"une exception non envisagee a ete lancee, l'application va quitter";
            exit(1);
        }
    }
    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. #29
    Membre confirmé
    Inscrit en
    Juin 2008
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 140
    Par défaut
    Merci pour cette indication, je regarde cela.

  10. #30
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2008
    Messages : 87
    Par défaut
    std::find ca ne va pas ?

  11. #31
    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
    Si il utilisait un std::map avec pour clé m_id, oui on aurait pu utiliser la méthode find, mais dans ce cas là, tu ne peux pas utiliser un find.

    Il faudrait redéfinir l'opérateur d'égalité pour pouvoir utiliser find.

  12. #32
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Sans redéfinir l'opérateur d'égalité, on peut utiliser un foncteur approprié.
    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.

  13. #33
    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
    Par défaut
    Le post part vraiment sur plein de sujets, dur à suivre !

    Citation Envoyé par Nogane Voir le message
    Bonsoir,
    Pour répondre a la question initial je pense que j'aurais ajouté une exception, du style:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    throw std::logic_error("Cette ligne ne devrait pas être atteinte");
    plutot qu'un "return NULL".
    Il y as trois raison a cela:
    1 - Le relecteur du code sait immédiatement a quoi s'en tenir
    2 - Comme le "return", ça fait taire le warning
    3 - On as pas besoin(ni même l'idée) de tester la valeur retournée à la sortie de la fonction.
    Personnellement moi ici je met un assert qui fait sauter l'exécution direct. Pour moi l'exception doit être utilisée dans le cas où l'erreur doit être gérée dans un cas d'utilisation possible du programme. Si la précondition n'est pas respectée ici, c'est sûrement la faute d'un développeur et pas du système ou de l'utilisateur. Donc assert et correction obligatoire du code incriminé.

    Bien sûr cela dépend du contexte (ma position n'est peut être pas valable pour du code embarqué critique).

  14. #34
    Membre confirmé
    Inscrit en
    Juin 2008
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 140
    Par défaut
    Citation Envoyé par jblecanard Voir le message
    Le post part vraiment sur plein de sujets, dur à suivre !

    Personnellement moi ici je met un assert qui fait sauter l'exécution direct. Pour moi l'exception doit être utilisée dans le cas où l'erreur doit être gérée dans un cas d'utilisation possible du programme. Si la précondition n'est pas respectée ici, c'est sûrement la faute d'un développeur et pas du système ou de l'utilisateur. Donc assert et correction obligatoire du code incriminé.

    Bien sûr cela dépend du contexte (ma position n'est peut être pas valable pour du code embarqué critique).
    Bonjour et merci à tous pour vos réponses.
    En fait, la seule fois où l'élément n'existe pas serait (je pense) dans le cas d'une allocation mémoire impossible d'un élément dans le vecteur (pas assez de mémoire). Le vecteur d'éléments est construit une fois pour toute au début de l'exécution du programme et ensuite durant toute l'exécution les appels à cette fonction de recherche ne se font que pour des ID existants (c'est sûr).

  15. #35
    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 Bousk Voir le message
    Sans redéfinir l'opérateur d'égalité, on peut utiliser un foncteur approprié.
    +++
    En C++11, ça devient une ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Element& searchElement( std::vector< Element * >& aVectorOfElements , std::string const &anId )
    {
       return **std::find_if(std::begin(aVectorOfElements),std::end(aVectorOfElements),[&anId](Element const*e_){return e_->m_id==anId;});
    }

  16. #36
    Membre confirmé
    Inscrit en
    Juin 2008
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 140
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    +++
    En C++11, ça devient une ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Element& searchElement( std::vector< Element * >& aVectorOfElements , std::string const &anId )
    {
       return **std::find_if(std::begin(aVectorOfElements),std::end(aVectorOfElements),[&anId](Element const*e_){return e_->m_id==anId;});
    }
    Je vais regarder cela plus en détail (notamment ce qu'est un foncteur).

  17. #37
    Membre expérimenté Avatar de Nogane
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 241
    Par défaut
    Citation Envoyé par jblecanard Voir le message
    Le post part vraiment sur plein de sujets, dur à suivre !



    Personnellement moi ici je met un assert qui fait sauter l'exécution direct. Pour moi l'exception doit être utilisée dans le cas où l'erreur doit être gérée dans un cas d'utilisation possible du programme. Si la précondition n'est pas respectée ici, c'est sûrement la faute d'un développeur et pas du système ou de l'utilisateur. Donc assert et correction obligatoire du code incriminé.

    Bien sûr cela dépend du contexte (ma position n'est peut être pas valable pour du code embarqué critique).
    Je n'ai absolument rien contre l'assert, mais rappelons que la question de départ était de faire taire le warning, ce que ne fera pas l'assert. Biensur, on peut cumuler assert et throw.
    Rappelons quand même que l'exception logic_error doit signaler une erreur dans le code, exactement comme l'assert, et n'est donc pas si éloigné que ça de l'assert dans sa signification(même si les conséquence sont différentes).

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par jblecanard Voir le message
    Personnellement moi ici je met un assert qui fait sauter l'exécution direct. Pour moi l'exception doit être utilisée dans le cas où l'erreur doit être gérée dans un cas d'utilisation possible du programme. Si la précondition n'est pas respectée ici, c'est sûrement la faute d'un développeur et pas du système ou de l'utilisateur. Donc assert et correction obligatoire du code incriminé.

    Bien sûr cela dépend du contexte (ma position n'est peut être pas valable pour du code embarqué critique).
    Je vois, personnellement deux gros problèmes à l'utilisation des seules assertions.

    Le premier (que j'admets beaucoup plus volontiers pour les exceptions) est que ce n'est pas parce que, en période de tests (qu'il soient unitaires ou basés sur des scénarios de manipulation réelle) tu n'as pas une assertion que cela veut, d'office, dire que ton code est correct...

    Cela veut "simplement" dire que, pour l'instant, tu n'as pas encore trouvé le moyen de mettre ton système dans un état dans lequel l'assertion surviendrait

    Je suis le premier à reconnaitre la vertu des tests unitaires et des tests d'utilisation courante, mais ce n'est, de manière générale, pas parce que ton système les passe haut la main qu'il n'y a strictement aucun problème, cela veut dire, tout simplement, que "en l'état", tu n'as pas encore trouvé le moyen de mettre le système en défaut

    Le deuxième que je trouve aux assertions tient à leur nature même qui veut qu'elles ne soient actives qu'en mode débug.

    Cela signifie que, dés que tu présentes une version release, les assertions sont, purement et simplement, supprimées de l'exécutable et que, bien souvent on va avoir un "crash inexpliqué" qui survient en utilisation réelle (mais donc en version release) justement parce que la seule protection était... un assert, certes judicieux, mais qui n'est pas actif dans la release

    Et c'est quelqu'un qui travaille sur un projet qui contient plus d'assertions que de fonction qui écrit ces lignes
    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

  19. #39
    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
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Je vois, personnellement deux gros problèmes à l'utilisation des seules assertions
    Ne me faites pas dire ce que je n'ai pas dis
    j'ai dit que dans ce cas précis, je met une assertion, car c'est une zone de code qui n'est pas censée être exécutée, et que le système ne doit pas être dans cet état et que s'il s'y retrouve, je dois en être informé aussi tôt que possible et de la manière la plus brutale qui soit, en développement.

    De toute évidence, les assertions seules ne suffisent pas comme métrique de qualité et de fiabilité, là dessus (et sur le reste de ta réponse), je suis absolument d'accord ! D'ailleurs, rien n'empêche de coder une assertion brutale en dev qui se signale de manière plus douce en release. On ne peut pas rattraper proprement tous les cas d'erreurs qui proviennent d'états dans lequel le système n'est pas censé se trouver, sinon on finit jamais le dev

Discussions similaires

  1. Affectation de variable boucle FOR à l'intérieur d'une boucle WHILE
    Par Droïde Système7 dans le forum Débuter
    Réponses: 10
    Dernier message: 05/11/2007, 19h11
  2. : remplir des zones de texte avec une boucle For
    Par Haro_GSD dans le forum Access
    Réponses: 3
    Dernier message: 20/09/2005, 21h23
  3. Problème avec une DLL dans une boucle For
    Par BraDim dans le forum Langage
    Réponses: 5
    Dernier message: 20/09/2005, 12h22
  4. [batch] incrémentation dans une boucle for
    Par bart64 dans le forum Scripts/Batch
    Réponses: 4
    Dernier message: 08/09/2004, 20h05
  5. Réponses: 3
    Dernier message: 06/07/2004, 10h21

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