Debug assertion failed, quesako? [C++] - C++ - Programmation
Marsh Posté le 11-03-2003 à 22:28:03
Alload a écrit : C'est bien les erreurs que je connais même pas |
T'as pêté un contrat, comme c'est du C++, pour trouver où il est écrit, c'est pas gagné. Peut-être dans la doc de la lib qui contient le new (je pense que c'est le new vu le nom la fonction de vérification), ou avec la doc du compilo. Si tout se passe comme d'hab, c'est uniquement dans le code source.
Il est possible aussi que ça ne vienne pas de toi (si tu es _sur_ de pas faire de conneries avec la mémoire) mais je pense plutôt que tu fais une connerie avec la mémoire et que tu bousille un mot magique auquel tu ne devrait pas toucher, vérifie toutes tes bornes de tableaux et accès pointeurs. Je pense que la connerie est faite il y a longtemps et que tu la détecte uniquement avec le new (plus exactement _CrtCheckMemory()).
Bienvenue dans un monde de merde, un monde de C++.
Heu ... quand je dis : "Je pense", je spécule.
Marsh Posté le 11-03-2003 à 22:29:54
Alload a écrit : Je vois pas ce qui cloche sachant que mon code marche n fois mais plante la n+1 ième fois. |
tu regardes l'aide :
_CrtCheckMemory()
Confirms the integrity of the memory blocks allocated in the debug heap (debug version only).
tu pines la mémoire qq part dans ton programme. des fois ça passe, des fois ça casse. en tout cas, ce n'est certainement pas ton alloc qui plante.
Marsh Posté le 11-03-2003 à 22:31:02
ReplyMarsh Posté le 11-03-2003 à 22:31:26
Oki merci je vais essayer de voir si quelque chose cloche avant.
Marsh Posté le 11-03-2003 à 22:33:35
youdontcare a écrit : jamais t'arrête, toi ? |
il semblerait plutôt que ce soit lui qui ne se soit pas arrêté quelquepart où il aurait dû.
-->[]
Marsh Posté le 11-03-2003 à 22:35:38
fo dire que les assertions, ca devrait pas exister en C++ (déjà qu'en C)
les exceptions, c'est pas pour les chiens
Marsh Posté le 11-03-2003 à 22:35:56
nraynaud a écrit : |
nraynaud... tu deviens pénible
(ceci dit, elle est excellente )
Marsh Posté le 11-03-2003 à 22:45:56
++Taz a écrit : fo dire que les assertions, ca devrait pas exister en C++ (déjà qu'en C) |
Un petit tour dans Meyer te ferait du bien, je crois.
edit: ce qui n'empêche pas que les assertions devraient lever des exceptions (mais bon, on connais le discours de Strustroup là dessus).
edit2 : le pb c'est qu'il va bien y avoir un tocard pour les trapper et continuer.
Marsh Posté le 12-03-2003 à 07:43:27
je sais très bien ce que dit Meyer. Mais tu admettra toi même que la plus part des programmeurs C++ utilise des assert là ou il faut des exceptions. Après c'est sur que du aux lacunes du C++, fo se cogner des assert. Mais il vaut mieux utiliser des static_assert comme ceux de boost...
Marsh Posté le 12-03-2003 à 09:48:18
++Taz a écrit : |
??? Tu peux développer. Je ne vois pas comment on peux utiliser des assert à la place des exceptions, sachant que cela n'a pas le même rôle. Mon code est truffé d'assert, et je fais tourner mes softs écrit en c++ pendant un moment en debug. Au moins si ca plante, tu peux retrouver tout le contexte d'execution. Ce sert à quoi de lever une exception pour dire qu'il y a un pb, puisque assert le fait très bien? Bon, ce n'est valable qu'avec des versions compilée en mode debug.Un assert, c'est définif, alors qu'une exception ca se catch. je ne vois pas comment utiliser l'un à la place de l'autre.
Marsh Posté le 12-03-2003 à 11:20:59
Parce que tu ne te places que du point de vue du développement. En production, les asserts, c'est la catastrophe, parce qu'une appli ne devrait jamais planter, même sur assertion violée : elle devrait toujours être capable de récupérer sur erreur.
Marsh Posté le 12-03-2003 à 12:51:23
BifaceMcLeOD a écrit : Parce que tu ne te places que du point de vue du développement. En production, les asserts, c'est la catastrophe, parce qu'une appli ne devrait jamais planter, même sur assertion violée : elle devrait toujours être capable de récupérer sur erreur. |
exactement.
Je suis surtout intervenu dans ce sujet par ce que, bien que je ne connaisse rien à la programamtion sous windows, le comportement que decrit Alload me semble etre le parfait exemple d'une mauvaise conception (et heureusement que l'assert est resté sinon on aurait pas vu d'erreur.)
Le problème ici, c'est qu'on se retrouve devant une assertion qui surgit des entrailles de l'implémentation, sans aucun sens pour l'utilisateur, alors que, selon la norme qui est bien faite à ce niveau là, une allocation qui echoue doit lancer une exception std::bad_alloc, ce qui est un évènement explicite et gérable.
Bref, si les les programmeurs de compilateur avaient compilé en release, tu serais encore à chercher d'ou vient le problème, ou tu ne saurait meme pas qu'il y en a un.
Marsh Posté le 12-03-2003 à 12:56:39
comme dit par BifaceMcLeOD, les assert, ça fait planter ton programme.
sowhatin22 a écrit : Au moins si ca plante, tu peux retrouver tout le contexte d'execution. |
si tu es le seul à utiliser ton code et si le volume de code n'est pas important, oui tu peux retrouver le contexte et peut etre arriver à comprendre pourquoi l'assertion à echouée. sinon, que fera un autre programmeur de ton assert? crois tu vraiment qu'un utilisateur soit satisfait d'un "assertion failed truc.cpp line 69" ?
Marsh Posté le 12-03-2003 à 13:03:11
Citation : Bref, si les les programmeurs de compilateur avaient compilé en release, tu serais encore à chercher d'ou vient le problème, ou tu ne saurait meme pas qu'il y en a un. |
Non, l'assert qu'il a recu fait parti du code de debug que visual te rajoute automatiquement (entre autre, il en met un peu partout et pas seulement pour les allocs)
A vu de nez ce n'est pas l'allocation en elle-meme qui plante, il a surtout du barbouiller en ram un peu n'importe ou avant
Marsh Posté le 12-03-2003 à 13:40:22
chrisbk a écrit : |
j'aime encore moins VC++
enfin, merci de la précision
Marsh Posté le 12-03-2003 à 13:41:25
BifaceMcLeOD a écrit : Parce que tu ne te places que du point de vue du développement. En production, les asserts, c'est la catastrophe, parce qu'une appli ne devrait jamais planter, même sur assertion violée : elle devrait toujours être capable de récupérer sur erreur. |
C'est une fausse vérité parce que en production, on doit avoir une version 'release' ou le assert 'ne fait rien'. L'assertion ne doit servir que dans des phases de test, pas une fois la livraison effectuée.
De plus, je me répète, l'assertion permet de vérifier une condition en mode debug. Quel est l'interêt de générer une exception si cette condition n'est pas satisfaite? Pourquoi ne pas simplement retourner un code d'erreur? Et qui va catcher l'exception? C'est bien de lever une exception, mais encore faut-il qu'elle soit interceptée par qq'un qui sache ce qu'il peut être amené à intercepter.
Ceci dit, à en coire ton commentaire ainsi que d'autres avant, il faudrait pouvoir implementer dans le C++ tous les méchanismes qui l'on été dans Eiffel avec la technique de programmation par contrat, les clauses de rescue, etc... Auquel cas le mechanismes des exceptions en C++ pourrait être utiliser pour re-inventer ces procédés, mais cela me parait assez lourd, non?
Allez, on crée une sous rubrique eiffel :-D en plus j'ai commencé à m'y mettre il n'y a pas longtemps, alors peut être que je pourrais participier un peu :-)
Marsh Posté le 12-03-2003 à 13:51:40
sowhatin22 a écrit : |
donc tu as la faculté de détecter un bug mais tu la planque ?
L'interêt c'est que tu as perdu toute garantie sur l'état de ton programme, donc que tu ne peux pqs continuer puisque tu ne sais pas ce que tu vas éclater.
Evidemment, tu peux aussi désactiver les assertions, tout planquer et faire croire que tu as un logiciel qui marche, mais j'espère que tu va assez rapidement te retrouver au chômage et laisser ta place à quelqu'un de responsable.
Apprend la soudure, ça paye bien et y'a du boulot (mais évite de masquer le travail mal fait).
edit : j'ai oublié un bout du message
évidememnt, c'est pour des raisons de performance qu'on vire les assert en release (un petit forall bien placé ça tue bien en complexité)
Marsh Posté le 12-03-2003 à 14:07:27
++Taz a écrit : j'aime encore moins VC++ |
?
Au contraire c tres pratique (c pas l'alloc qui a plantee, la)
Marsh Posté le 12-03-2003 à 14:42:07
nraynaud a écrit : |
??? De quoi tu me parles, là? J'ai simplement dit que le assert ne fait rien en release, ca s'arrete là. Donc si plantage il doit y avoir, eh ben ca plante. Et c'est pas le fait de générer une exception qui va changer quoi que ce soit...
nraynaud a écrit : |
C'est exactement ce que je dis: je préfère que le programme se plante plutôt que de catcher une exception que je ne sais de toute façon pas gérer et continuer comme si rien ne s'était passé.
nraynaud a écrit : |
Va voir quelques post plus hauts: "Mon code est truffé d'assert...".
Tu as plein de choses interressantes à dire, mais j'ai parfois l'impression que tu t'enfammes un peu vite. Prends le temps de lire les post en intégralité avant d'allumer. 'si tu ne penses pas comme moi, tu es un irresponsable donc vas faire de la soudure', d'abord c'est avoir bien peu de considération pour ceux qui font de la soudure, ensuite c'est assez peu constructif, et enfin c'est nul puisque si tu avais pris le temps, tu aurrais vu que je dis la même chose que toi.
Marsh Posté le 12-03-2003 à 14:56:45
je numérote, ça me saoule les balises
sowhatin22 a écrit : |
1) ça arrête les conneries dès que possible, pas quand le mec a sauvé ses 100 heures de travail (bien évidement, corrompues par le bug et irrécupérables).
2) tu laisses le handler par défaut catcher si t'en veux pas, sinon, tu peux formatter l'exception pour l'utilisateur et te casser (à la différence des assertions en C++).
3) ma vie est passinante si tu savais ...
4) je te proposais de changer d'activité vers un truc où il y a du boulot bien payé, si j'avais voulu vanner une profession, je t'aurais proposé de rester en info.
5) "C'est une fausse vérité parce que en production, on doit avoir une version 'release' ou le assert 'ne fait rien'. L'assertion ne doit servir que dans des phases de test, pas une fois la livraison effectuée." n'est pas exactement ma ligne de conduite.
Question subsidiaire à propos des contrats : Quelle contrainte est induite par les préconditions et qui n'existe pas (explicitement) en C++ ?
Marsh Posté le 12-03-2003 à 15:14:36
nraynaud a écrit : |
je n'imagine même pas une seconde qu'on me laissera faire une livraison d'un programme en debug.
nraynaud a écrit : |
aucune. mais comme je le disais plus haut, je préfère un code d'erreur en retour de fonction plutôt que la génération d'une exception. Question de choix.
Marsh Posté le 12-03-2003 à 15:32:07
sowhatin22 a écrit : |
Y'a du boulot pour eiffel !!!
Pour sortir de la qualité aussi.
Marsh Posté le 12-03-2003 à 15:59:17
nraynaud a écrit : |
J'espère que si il t'arrive d'enseigner, tu es un peu moins arroguant avec ceux qui t'écoutent que tu ne peux l'être ici. Je ne comprends pas l'intérêt qu'il peut y avoir à être si arrogant, si ce n'est de décourrager ceux qui débutent. Egoïsme, prétention, autre? Tu en sais plus que moi? Il y a plein de gens qui en savent plus que moi. Ce n'est pas un soucis, au contraire. Mais alors je suis preneur de conseils, pas de sarcasmes.
Oui, il y a du boulot pour eiffel. J'espère pouvoir en parler avec des gens qui aurront plaisir à en parler avec moi.
Marsh Posté le 12-03-2003 à 16:05:39
sowhatin22 a écrit : |
on voit que tu n'as pas eu à développer des applications fiables où toutes les sources d'erreur sont détectées et traiter. tester 1 retour de fonction, ça va. en traiter 10 par fonctions et analyser leurs codes à la main pour savoir que faire, c'est une autre paire de manche.
Marsh Posté le 12-03-2003 à 16:07:15
sowhatin22 a écrit : |
y a pas d'arrogance dans les propos de nraynaud. tout ce qu'il dit est juste et le ton qu'il emploie est le bon: on ne peut pas se permettre de plaisanter avec la fiabilité des programmes.
Marsh Posté le 12-03-2003 à 16:11:43
++Taz a écrit : on voit que tu n'as pas eu à développer des applications fiables où toutes les sources d'erreur sont détectées et traiter. |
Si
Marsh Posté le 12-03-2003 à 16:26:47
++Taz a écrit : j'en doute sérieusement. ou alors t'es payé à la ligne |
c'est pas parce qu'on n'utilise pas les exceptions qu'un programme est nul! c'est quoi ce délire. Parce que je fais pas comme vous, alors c'est pas bien. Note au passage qu'à ce moment là, tous ceux qui font du C sont dans le même cas.
Mais continue à douter si tu y tiens. Il n'y a pas d'exceptions, et pourtant cela fonctionne. Et je ne suis pas payé à la ligne.
Je viens pour avoir des discutions interessantes et on ne trouve rien de mieux à me dire que ce que je fais est nul. C'est désolant.
Je suis quelque peux amer.
t'énerve plus, je passe mon chemin.
Marsh Posté le 12-03-2003 à 16:29:31
évidemment que le C fonctionne: mais le fait est que quand je fais un programme en C, 70% de mon code sert à tester les retours de fonctions.
Marsh Posté le 12-03-2003 à 16:35:39
sowhatin22 a écrit : |
Alors explique-moi pourquoi les exceptions ont été inventées.
Parce que les codes d'erreur en retour de fonction, c'est exactement ce qu'on faisait, avant, en C par exemple.
Réponse : parce que ce n'est pas satisfaisant. Comme le dit Taz, quand tu appelles successivement 10 fonctions, et que tu dois récupérer le code d'erreur pour chacune d'entre elles, soit tu oublies volontairement de récupérer le code d'erreur parce que c'est gonflant -- ce que font au bas mot 9 programmeurs sur 10 --, soit tu joues les super-rigoureux et tu récupères systématiquement les codes d'erreur. Si effectivement tu le fais, tu obtiens alors un code peu lisible et délicat à maintenir, surtout que dans 9 cas sur 10, la récupération sur erreur est la même. Ce qui veut dire que le code de récupération sur erreur sera dupliqué, d'où risque important de bugs (parce qu'il y aura bien une ou deux versions du code qui différeront). Ou alors tu utilises le goto pour centraliser le code de gestion de l'erreur, ce qui brise la structure du code et rend rarement le code plus lisible. A moins d'utiliser les exceptions, qui ne sont rien d'autre que des gotos sur erreurs.
edit> Pour ton problème, je ne vois pas comment savoir quelle instruction fout ta mémoire en l'air, à part utiliser un outil de diagnostic mémoire, type Purify, qui va vérifier et diagnostiquer chacun des accès à la mémoire que tu fais dans ton programme. Parce que clairement, quand ton assertion arrive, il est déjà beaucoup trop tard.
Marsh Posté le 12-03-2003 à 16:37:54
sowhatin22 a écrit : |
Il existe effectivement des techniques pour controurner en sécurité les exceptions (genre pattern-matching ou, plus couillu, les exceptions monadiques), mais elles ne sont pas présentes dans le C++
Quand à dire que le C est un langage de merde, très adapté à produire d'autres merdes ... Je suis connu pour ça !¡!
(désolé pour le temps de réponse, j'étais en réunion)
Marsh Posté le 12-03-2003 à 16:47:04
sowhatin22 a écrit : |
Les informaticiens ont inventé, au fur et à mesure de leurs besoins, des outils de plus en plus puissants, de plus en plus efficaces, et qui répondaient de mieux en mieux à leur besoin primordial : écrire des programmes qui fonctionnent (et dont on puisse être sûr qu'ils fonctionnent).
C a été inventé en 1969, si ma mémoire est bonne, il y a donc 34 ans, ce qui fait beaucoup à l'échelle de l'histoire de l'informatique. Très clairement, d'autres langages ont été inventés depuis pour corriger les problèmes que C posait. Autrement dit, C n'est pas nul, mais on a fait beaucoup mieux depuis.
Marsh Posté le 12-03-2003 à 16:47:07
sowhatin22 a écrit : |
Bien au contraire, à faire réagir, pour sortir, tête du cul, rien de tel qu'une bonne secousse.
C'est ce qui m'est arrivé il y a 2 ans avec un prof de smalltalk (oui, je sais on peut pas faire de qualité avec mais c'est plus compliqué que ça).
D'autre part, j'ai du plaisir à parler de Eiffel, mais pas avec un mec qui va aller faire volontairement du C en Eiffel et qui surtout ne prendra pas ce qui est intéressant dedans (en gros ce qu'il ne connait pas).
Marsh Posté le 12-03-2003 à 16:49:44
BifaceMcLeOD a écrit : |
J'avoue que justement, je me suis toujours demandé à quoi servent réellement les exceptions... Ton explication m'interesse. Aurais-tu un(des) lien(s) sur un(des) exemple(s) concret(s)?
Marsh Posté le 12-03-2003 à 16:50:30
briseparpaing a écrit : |
Le risque de la diminution de performances est une légende, liée aux premières implémentations des compilateurs C++ proposant les exceptions. Depuis lors, les compilateurs ont d'ailleurs fait beaucoup de progrès.
Mais je le répète : le mécanisme d'exceptions n'est ni plus ni moins qu'un goto sur erreur. Et même s'il était 10 % ou 20 % plus lent qu'un vrai goto, la sécurité qu'il offre serait incomparablement plus élevée que cette petite perte.
Marsh Posté le 12-03-2003 à 16:52:24
Ne perds pas de vue qu'un programme qui ne fonctionne pas est d'une utilité quasi nulle.
apres il faut savoir faire le bon dosage: une exception doit etre exceptionnelle, pas la peine de lancer des exceptions à tour de bras (n'est ce pas Java EOFException) : à toi de juger, documentes toi, si tu as du mal à choisir, soumets les. Effectivement les blocs try/catch sont un peu plus lents, mais tu as tous les avantages cités plus haut.
Marsh Posté le 12-03-2003 à 16:53:36
briseparpaing a écrit : |
En réalité, compiler des exceptions est galère, tu ne peux pas trop modifier le graphe d'appel des fonctions de façon que le chemin de remontée des exceptions soit celui attendu.
Mais perso (il semble qu'on ne soit pas nombreux dans ce cas) entre un programme qui fonctionne lentement et un programme qui plante vite, mon choix est tout fait.
Marsh Posté le 12-03-2003 à 16:58:06
sowhatin22 a écrit : |
Pas de lien, désolé.
Comme je le disais, c'est un "goto sur erreur" masqué (comme le "while" et le "for" sont des gotos conditionnels).
En C, les fonctions qui traitent les erreurs ont souvent la structure suivante :
Code :
|
C'est ce qu'on a trouvé de plus lisible pour centraliser la désallocation des ressources, et donc éviter la duplication de ce code. Mais tu remarqueras que cela utilise des gotos, ce qui n'est guère lisible, et rompt la structure de la fonction (les appels de fonction peuvent se trouver dans des boucles).
Avec un mécanisme d'exceptions, on a un code similaire, mais plus lisible :
Code :
|
Autre avantage : non seulement la fonction peut récupérer sur erreur, mais l'appelant peut faire de même si la fonction ne souhaite pas traiter l'erreur.
Marsh Posté le 11-03-2003 à 22:08:29
C'est bien les erreurs que je connais même pas
Enfin bref, voici le probleme. A un moment j'essaie de créer un tableau de DWORD* de cette manière:
DWORD **ppTest = new DWORD*[valeur];
Desfois ça marche et desfois ça m'affiche cette erreur:
"Debug Assertion Failed!
[...]
Expression: _CrtCheckMemory()
[...]"
Quelqu'un connait cette erreur? Je vois pas ce qui cloche sachant que mon code marche n fois mais plante la n+1 ième fois.
Merci!