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 :

Assertion vs Exception, dans quels cas utiliser l'une ou l'autre ?


Sujet :

C++

  1. #1
    Membre habitué Avatar de Kromagg
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2008
    Messages
    275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Août 2008
    Messages : 275
    Points : 198
    Points
    198
    Par défaut Assertion vs Exception, dans quels cas utiliser l'une ou l'autre ?
    Bonjour,

    Je me posais la question suivante: dans quels cas faut-il utiliser les exceptions à la place des assertions, et inversement ?
    Actuellement j'utilise les assertions pour vérifier en entrée d'une fonction/méthode que toutes les conditions sont remplies (pas de pointeur nul, pas d'index en dehors de l'intervalle requis...) et j'utilise les exceptions pour des erreurs d'exécution du genre ouverture de fichiers...

    Merci
    C'est dans ses rêves que l'homme trouve la liberté cela fut, est et restera la vérité! (John Keating - Le cercle des poètes disparus)

  2. #2
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Hello,

    Ça me semble une bonne utilisation.

    Les exceptions sont là pour toutes les erreurs imprévisibles (exceptionnelles ?) qui ne dépendent pas du code (comme une erreur d'entrée / sortie : fichier manquant par exemple).

    Pour tester les pré/post conditions des fonctions les assertions sont bien : si ça passe en debug, ça passera en release et les assert disparaissent.

  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Les assertions servent à tester des comportements attendus du code, tels que si l'assertion foire, c'est forcément une erreur dans le code, et non un problème extérieur (fichier manquant, etc.)
    Par exemple, tester les invariants de sortie d'une fonction, avant que la fonction retourne. Si la fonction doit remplir un buffer de chaîne, on asserte que le buffer est toujours terminé par \0 à la fin. Si l'assertion échoue, ça montre un bug dans la fonction vu qu'elle ne respecte pas un invariant de sortie.

    En revanche les exceptions sont pour des erreurs hors du contrôle du programmeur (ou dans le cas d'une bibliothèque, hors du contrôle de son créateur). Par exemple, un fichier indispensable manquant ou une clé requise non-trouvée dans un dictionnaire (pour un fichier ou une clé optionnels, un bête retour de valeur d'erreur peut être préférable).

    Pour vérifier les paramètres d'une fonction, le choix entre exception et assertion dépend du contexte, du fait que la fonction soit publique ou interne, des traditions de la plate-forme, et de la probabilité que le respect d'une règle (genre: cet argument ne doit jamais être nul) puisse changer d'une exécution à l'autre:
    • S'il y a un risque que l'erreur soit présente en Release, on utilisera forcément une exception.
    • Si la fonction est interne et que son appelant est supposé avoir déjà vérifié les pré-conditions, on utilisera une assertion.
    • etc.
    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
    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
    Assertions -> erreurs de programmation
    Exception -> erreurs de contexte.
    Utiliser les exceptions pour de l'erreur de programmation, c'est de la programmation défensive, et cela a vite fait de masquer les problèmes réels (même si cela "stabilise" le logiciel en production).
    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...

  5. #5
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par Iradrille Voir le message
    Hello,

    Ça me semble une bonne utilisation.

    Les exceptions sont là pour toutes les erreurs imprévisibles (exceptionnelles ?) qui ne dépendent pas du code (comme une erreur d'entrée / sortie : fichier manquant par exemple).

    Pour tester les pré/post conditions des fonctions les assertions sont bien : si ça passe en debug, ça passera en release et les assert disparaissent.
    Ce n'est hélas pas suffisant. Un test de validité des pré/post-condition doit toujours s'accompagner d'un mécanisme qui renvoie une erreur à l'appelant en cas de violation - sans quoi, ton programme release risque de laisser passer certains cas que tu pourrais ne pas avoir trouvé en debug (parce que ton ensemble de données de test sera plus grand une fois ton application déployée).

    Je voudrais revenir sur un point : le fait de réserver les exceptions à de erreurs exceptionnelles est débattable. De fait, c'est le seul moyen qu'on a de renvoyer une erreur dans un constructeur (quel que soit le degré d'exceptionnalité de l'erreur en question). Ensuite, le stack unwind implicite est du même ordre (en terme de pénalité sur les performances) que le stack unwind explicite lié au test d'un code d'erreur. Un des problèmes liés aux exceptions est qu'il fragilise globalement le code si on y prends pas garde, et que leur utilisation casse le flux de contrôle du programme (pouvant rendre celui-ci plus complexe à appréhender lorsqu'on débogue un problème).

    Ceci dit, ces problèmes sont compensés par le fait que leur seule présence (et utilisation) permet d'affiner le sens du code.

    Un exemple simple : si une fonction n'a pas besoin de renvoyer quoi que ce soit, alors sémantiquement il est plus juste de la définir avec un type de retour void. Si cette fonction peut traiter des cas d'erreur, alors l'utilisation d'exception permet de préserver sa sémantique (qui n'est plus préservée si on renvoie un code d'erreur).
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  6. #6
    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 Emmanuel Deloget Voir le message
    Ce n'est hélas pas suffisant. Un test de validité des pré/post-condition doit toujours s'accompagner d'un mécanisme qui renvoie une erreur à l'appelant en cas de violation - sans quoi, ton programme release risque de laisser passer certains cas que tu pourrais ne pas avoir trouvé en debug (parce que ton ensemble de données de test sera plus grand une fois ton application déployée).
    Cela a été un de mes cauchemars lors d'une précédente mission
    Je voudrais revenir sur un point : le fait de réserver les exceptions à de erreurs exceptionnelles est débattable. De fait, c'est le seul moyen qu'on a de renvoyer une erreur dans un constructeur (quel que soit le degré d'exceptionnalité de l'erreur en question). Ensuite, le stack unwind implicite est du même ordre (en terme de pénalité sur les performances) que le stack unwind explicite lié au test d'un code d'erreur. Un des problèmes liés aux exceptions est qu'il fragilise globalement le code si on y prends pas garde, et que leur utilisation casse le flux de contrôle du programme (pouvant rendre celui-ci plus complexe à appréhender lorsqu'on débogue un problème).

    Ceci dit, ces problèmes sont compensés par le fait que leur seule présence (et utilisation) permet d'affiner le sens du code.

    Un exemple simple : si une fonction n'a pas besoin de renvoyer quoi que ce soit, alors sémantiquement il est plus juste de la définir avec un type de retour void. Si cette fonction peut traiter des cas d'erreur, alors l'utilisation d'exception permet de préserver sa sémantique (qui n'est plus préservée si on renvoie un code d'erreur).
    Je suis --globalement-- d'accord avec toi.

    Cependant, à force de vouloir renvoyer des codes d'erreur ou lancer des exceptions, on en arrive à une mode de programmation "défensive" qui tôt ou tard nuira très fortement aux performances globales de l'application.

    Je suis donc d'accord avec Luc (et pour cause, nous avons eu l'occasion de discuter longuement du problème ) :

    Les assertions devraient, systématiquement, être utilisées pour détecter le erreurs de programmation: le fait qu'une collection est vide, alors qu'elle est sensée contenir au minimum un élément, qu'un pointeur soit nul alors qu'il n'aurait pas du l'être, qu'un index dépasse la capacité d'une collection, qu'une chaine de caractères respecte un pattern donné, j'en passe et de meilleure.

    Les exceptions devraient, quant à elles, être utilisées pour tout ce qui est "hors de controle" du développeur de l'application:
    • une connexion réseau défaillante (parce que le serveur est "down" ou qu'un psychopathe a coupé le fil)
    • un fichier inaccessible car "verrouillé" par une application tierce
    • une allocation dynamique de mémoire qui échoue (c'est l'OS qui donne la mémoire dynamique )
    • ...

    Lorsque l'on applique une politique de test (tests unitaires, mais aussi test manuelle de scénario clairement identifiés), il est "logique" de penser que tous les cas d'assertions devraient être couverts, meme si on ne peut s'empêcher de penser que cette politique ne fait que nous démontrer que l'on n'a pas encore réussi à prendre l'application en faute

    Mais, a priori, les erreurs de programmation devraient toutes avoir été corrigées avant la mise en production. Il n'y a donc aucune raison probante pour que les tests qui permettent de nous en assurer soient effectués en release
    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

  7. #7
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Citation Envoyé par Emmanuel Deloget Voir le message
    Ce n'est hélas pas suffisant. Un test de validité des pré/post-condition doit toujours s'accompagner d'un mécanisme qui renvoie une erreur à l'appelant en cas de violation - sans quoi, ton programme release risque de laisser passer certains cas que tu pourrais ne pas avoir trouvé en debug (parce que ton ensemble de données de test sera plus grand une fois ton application déployée).
    J'ai du mal à voir comment : les fonctions sont appelées avec les mêmes paramètres, s'il n'y à pas d'erreur en debug, il ne peut pas y en avoir en release (sauf éventuel problème d'optimisation trop agressive mais c'est hors sujet je pense).

    Si une fonction traite des données différentes en debug et release (parser des fichiers différents par exemple), alors on se retrouve dans le cas d'une erreur qui ne dépend pas du code et on utilise donc des exceptions.

    Quand à savoir s'il vaut mieux utiliser des exceptions ou un code de retour, je pense (et je pense que beaucoup d'entre vous ont le même point de vue) que les exceptions sont préférables dans 90% des cas.
    Citation Envoyé par koala01 Voir le message
    Mais, a priori, les erreurs de programmation devraient toutes avoir été corrigées avant la mise en production. Il n'y a donc aucune raison probante pour que les tests qui permettent de nous en assurer soient effectués en release
    A part les problèmes d'optimisations trop agressives "méchant compilo, il casse tout mon code !", il ne devrait pas y en avoir besoin non. Je ne vois en tout cas pas comment une erreur peut apparaître en release SI les assert / exceptions / code de retour ont étés utilisés correctement.

    Si vous avez un exemple d'erreur qui peut apparaître en release, je prend.

  8. #8
    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 Iradrille Voir le message
    Si vous avez un exemple d'erreur qui peut apparaître en release, je prend.
    Une erreur toute bête: une collection de pointeurs nu qui n'est pas correctement mise à jour après destruction d'un objet sous-jacent. On se retrouve avec une fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void foo(std::vector<UnType *> const & tab){
        for(auto const & it : tab){
            assert(it!=nullptr); //oupss, it ne vaut jamais nullptr
            it->doSomething(); // comportement indéfini en release si l'adresse mémoire correspondant à it a été libérée
                               // ou si it a bel et bien été remis à nullptr mais n'a pas été supprimé de la collection
        }
    }
    Ca devient rapidement un calvaire à déboguer, surtout quand il est difficile de définir le scénario qui a mené à cette situation
    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
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par Iradrille Voir le message
    J'ai du mal à voir comment : les fonctions sont appelées avec les mêmes paramètres, s'il n'y à pas d'erreur en debug, il ne peut pas y en avoir en release (sauf éventuel problème d'optimisation trop agressive mais c'est hors sujet je pense).
    La théorie dit que c'est vrai. Mais comme la théorie dit aussi qu'elle est identique à la pratique, il y a des fois où il vaut mieux être paranoïaque

    Le fait qu'aucune assertion ne soit levée en debug signifie juste que le chemin de code testé en debug est valide. Un changement dans les données initiales peut changer le flux du programme et provoquer des erreurs qui peuvent ne pas avoir été détectée en debug. D'où la nécessite de mettre les tests correspondants, afin que ces erreurs ne posent pas de problème en release.

    Citation Envoyé par Iradrille Voir le message
    Si une fonction traite des données différentes en debug et release (parser des fichiers différents par exemple), alors on se retrouve dans le cas d'une erreur qui ne dépend pas du code et on utilise donc des exceptions.
    Ce n'est pas tellement ça. Le problème est qu'en tant que programmeur (ou testeur), on travaille nécessairement sur un ensemble de donnée plus réduit que l'ensemble des données qui seront utilisée en production. On le conçoit naturellement si on fait un programme qui est distribué à plusieurs millions d'exemplaires : il y a des chances que les utilisateurs tombent sur un cas insuffisamment testé en debug - là où un assert l'aurait détecté.

    Citation Envoyé par Iradrille Voir le message
    Quand à savoir s'il vaut mieux utiliser des exceptions ou un code de retour, je pense (et je pense que beaucoup d'entre vous ont le même point de vue) que les exceptions sont préférables dans 90% des cas.A part les problèmes d'optimisations trop agressives "méchant compilo, il casse tout mon code !", il ne devrait pas y en avoir besoin non. Je ne vois en tout cas pas comment une erreur peut apparaître en release SI les assert / exceptions / code de retour ont étés utilisés correctement.
    Ma fois, si une erreur se produit en release, c'est qu'elle n'a pas été détecté avant, ce qui ne se produit que dans un seul cas : le jeu de test n'est pas assez important (mais dans certains cas il est impossible qu'il soit complet, ce qui signifie qu'il est nécessairement trop petit). Tous les code path ne sont pas testés ou le sont insuffisamment. A partir de là, on peut imagine tout et n'importe quoi.

    Je rappelle que mon métier est de créer des bugs (les gens appellent ça des logiciels, mais soyons réalistes : existe-t-il un logiciel non trivial qui soit exempts de bug ?), ce qui a comme propriété intéressante de me donner du travail à faire par la suite.

    Citation Envoyé par Iradrille Voir le message
    Si vous avez un exemple d'erreur qui peut apparaître en release, je prend.
    Si on part du principe que les assertions ne sont pas visibles en release, alors binutils est une source potentielle d'exemples (binutils garde les asserts en release ; si on rencontre un assert en utilisation normale, ça veut dire qu'enlever cet assert aurait provoquer un bug - quel que soit le bug en question).

    Je suis récement tombé sur un bug dans binutils (dans ld en fait) en créant une toolchain de cross compilation pour ARM big endian. En compilant uboot pour certaines plateformes ARM little endian, j'ai provoqué des assertions dans ld au lieu d'avoir un message d'erreur m'indiquant que ARMEB et ARMEL ne peuvent être linké ensemble.

    D'un point de vue plus générique, le fait de passer de debug en release change beaucoup de choses - certaines fonctions deviennent inline, voire intrisic, certaines macros n'ont plus le même comportement, etc. Du coup, le code testé en release est différent du code testé en debug (et je ne parle même pas des optimisations qui peuvent amener à un réordonnacement du code assembleur). Un assert peut tester la validité d'une valeur initialisée de manière indirecte dans un macro, la macro peut être différente en release pour des questions d'optimisation, et pouf - la valeur n'est plus initialisée de la même manière.

    Les scénariis sont aussi nombreux que les bugs possibles
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  10. #10
    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
    Le tout, sans oublier le cas où tu as un véritable singe qui fait du grand n'importe quoi avec son clavier et sa souris
    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

  11. #11
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Je n'avais pas pensé à ces points, je ne verrai plus les asserts comme "des protections ultime" contre les bugs.

  12. #12
    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 Iradrille Voir le message
    Je n'avais pas pensé à ces points, je ne verrai plus les asserts comme "des protections ultime" contre les bugs.
    Disons que, en théorie, les assertions sont des protections suffisantes contre les bugs.

    Mais pour que la théorie rejoigne la pratique, il faut une politique de test efficace et suffisante avant la mise en prod
    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
    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 on a outil du genre Coverity, on peut se permettre d'être moins parano.

  14. #14
    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
    Tout dépend ce que tu entends par parano. De sûr, avec clang-analyse ou l'option /analyse de VS, les assertions sont exploitées pour guider l'analyse statique de code.
    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...

  15. #15
    Expert confirmé Avatar de ManusDei
    Homme Profil pro
    vilain troll de l'UE
    Inscrit en
    Février 2010
    Messages
    1 619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : vilain troll de l'UE

    Informations forums :
    Inscription : Février 2010
    Messages : 1 619
    Points : 4 350
    Points
    4 350
    Par défaut
    Citation Envoyé par Iradrille Voir le message
    J'ai du mal à voir comment : les fonctions sont appelées avec les mêmes paramètres, s'il n'y à pas d'erreur en debug, il ne peut pas y en avoir en release (sauf éventuel problème d'optimisation trop agressive mais c'est hors sujet je pense).

    Si une fonction traite des données différentes en debug et release (parser des fichiers différents par exemple), alors on se retrouve dans le cas d'une erreur qui ne dépend pas du code et on utilise donc des exceptions.
    Je vais être un peu hors-sujet, mais je vais te donner un exemple du contraire.
    J'ai eu un programme où la libération de la mémoire se faisait plus tard dans la version Debug que dans la version Release.
    Je l'ai remarqué justement car ça faisait planter la version Release (j'accédais à une zone déjà libérée ET réécrite, alors qu'en Debug on avait pas réécrit par dessus donc les données lues étaient bonnes ).

    Pour un truc "simple", je parsais un fichier, construisait un arbre, et recrachais d'autres fichiers.
    http://www.traducteur-sms.com/ On ne sait jamais quand il va servir, donc il faut toujours le garder sous la main

  16. #16
    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 Iradrille Voir le message
    J'ai du mal à voir comment : les fonctions sont appelées avec les mêmes paramètres, s'il n'y à pas d'erreur en debug, il ne peut pas y en avoir en release (sauf éventuel problème d'optimisation trop agressive mais c'est hors sujet je pense).
    Simplement parce que l'utilisation réelle crée des conditions et des jeux de données qu'il est pas possible de prévoir avant. Dans ce que je fais, les utilisateurs créent des situations que nous n'avions pas prévues presque à chaque mise en prod (et c'est pas faute d'avoir des batteries de tests bien écrites).

    Citation Envoyé par Iradrille Voir le message
    Si vous avez un exemple d'erreur qui peut apparaître en release, je prend.
    J'y vais de mon exemple vicieux, rencontré avec GCC 4.7 : si tu implémentes une spécialisation template dans une unité de compilation (un *.cpp par exemple) et que tu oublies de la déclarer dans le header (et que tu linkes en statique, je pense que ça joue mais j'ai pas essayé en dynamique), alors tu peux te retrouver dans une situation ou ta spécialisation est bien appelée en debug et zappée en release. Pour peu que cette spécialisation soit un un peu subtile ou testable à l'échelle uniquement (une fonction de hash par exemple), et il se peut que tes tests passent à côté. Heureusement pour moi, les miens ont bien détecté le problème. Il faut toujours jouer le maximum de tests possibles en release.
    Find me on github

  17. #17
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par jblecanard Voir le message
    J'y vais de mon exemple vicieux, rencontré avec GCC 4.7 : si tu implémentes une spécialisation template dans une unité de compilation (un *.cpp par exemple) et que tu oublies de la déclarer dans le header (et que tu linkes en statique, je pense que ça joue mais j'ai pas essayé en dynamique), alors tu peux te retrouver dans une situation ou ta spécialisation est bien appelée en debug et zappée en release. Pour peu que cette spécialisation soit un un peu subtile ou testable à l'échelle uniquement (une fonction de hash par exemple), et il se peut que tes tests passent à côté. Heureusement pour moi, les miens ont bien détecté le problème. Il faut toujours jouer le maximum de tests possibles en release.
    Lorsque je le peux, j'exécute mes tests unitaires en release sur la machine cible. Ce n'est hélas pas toujours possible, mais ça permet de se mettre en condition d'utilisation (ce qui n'est pas rien : rien ne me dit que mon code écrit pour du 32 bits big endian n'ait pas un comportement différent en 64 bits little endian).

    Quelques règles que j'applique :

    * Et de manière générale, le code compilé en release est exactement le même que celui compilé en debug - aux assertions près.

    * Les macros n'ont donc pas le droit de faire des chose différentes en debug et release.

    * l'utilisation de ifdef/ifndef DEBUG/RELEASE est interdit dans mon code et dans le code dont je suis responsable.

    Ce qui permet d'avoir quand même une bonne idée de la façon dont le code devrait se comporter dans tous les cas (ce qui facilite le debug lorsqu'un problème est détecté).
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  18. #18
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par jblecanard Voir le message
    si tu implémentes une spécialisation template dans une unité de compilation (un *.cpp par exemple) et que tu oublies de la déclarer dans le header
    Note que c'est un comportement indefini (des que tu penses aux inlines, tu as compris pourquoi).
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

Discussions similaires

  1. Réponses: 55
    Dernier message: 18/03/2014, 12h11
  2. Dans quel cas utiliser PHP, .Net ou Java ?
    Par mic79 dans le forum Langage
    Réponses: 4
    Dernier message: 28/11/2008, 18h58
  3. Quand et dans quels cas utiliser les méthodes repaint() et validate()?
    Par kayzra dans le forum Interfaces Graphiques en Java
    Réponses: 14
    Dernier message: 02/08/2007, 15h46
  4. [Zope] Dans quel cas utiliser zope ?
    Par kalimero dans le forum Zope
    Réponses: 3
    Dernier message: 26/07/2005, 09h08
  5. [corba] débutant : dans quels cas l'utiliser
    Par jmturc dans le forum CORBA
    Réponses: 2
    Dernier message: 10/10/2002, 08h58

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