Comment attraper erreur d'exécution dans le C et le C++?
Comme la modification d'une CONST int
,
Puis-je enregistrer une fonction spécifique pour gérer les erreurs d'exécution, de sorte que ce genre d'opération juste échoue au lieu de l'arrêt de l'application?
C'est un peu un mauvais exemple -
Je pense que c'est un bon exemple, si c'est ce que l'OP se pose au sujet de. 🙂 Le type d'informations peut ne pas exister au moment de l'exécution, mais l'objet est toujours non-mutables, du point de vue sémantique, comme le programme s'exécute. Qui n'a pas simplement aller loin!
oui, il le fait en C si l'int arrive à être stockées sur la pile, vous n'obtiendrez pas un SIGSEGV ou tout autre type d'erreur à l'exécution, à moins que le compilateur a réussi à les répartir dans une zone protégée de la mémoire qui n'est pas possible en général
const
est purement une directive de compilation, et n'a aucune garantie de travail,à défaut ou de causer une erreur si vous parvenez à obtenir autour de la restriction à l'aide dangereux de conversion de type. Pas de compilateur, je sais de se "souvient" de la const
restriction à l'exécution...Je pense que c'est un bon exemple, si c'est ce que l'OP se pose au sujet de. 🙂 Le type d'informations peut ne pas exister au moment de l'exécution, mais l'objet est toujours non-mutables, du point de vue sémantique, comme le programme s'exécute. Qui n'a pas simplement aller loin!
oui, il le fait en C si l'int arrive à être stockées sur la pile, vous n'obtiendrez pas un SIGSEGV ou tout autre type d'erreur à l'exécution, à moins que le compilateur a réussi à les répartir dans une zone protégée de la mémoire qui n'est pas possible en général
OriginalL'auteur R__ | 2011-06-29
Vous devez vous connecter pour publier un commentaire.
Si vous voulez dire C++, il y a une certaine classe d'exception appelé
runtime_error
vous pouvez l'attraper avec une clause catchCependant, beaucoup de choses en C et C++ (comme la modification d'une const int) résultat de la undefined behvior. Vous ne pouvez pas attraper de l'exécution. Vous ne pouvez pas les attraper., parce qu'aucune exception n'est levée (techniquement, n'importe quoi peut arriver, y compris un lancer d'exception C++ seulement), mais ce n'est pas quelque chose que vous pouvez ou devez espoir pour)
La solution est d'écrire propre code de sécurité. Pour cela, il existe de nombreux conseils énumérés dans de nombreux livres 🙂
const
n'est évidemment pas l'un d'eux. Cela permet à l'ensemble du code fiable département, parfois trop, surtout si vous avez affaire avec des plugins ou autres de la 3e partie du code...De façon portable - vous pouvez pas, pouvez-vous?
Posix est assez portable dans mon expérience. Vraiment portable, non trivial, et C est généralement une combinaison rare.
OriginalL'auteur Armen Tsirunyan
De la modification d'une
const
est, selon les spécifications, "un comportement indéfini" de sorte que le compilateur ne peut rien faire. Dans la pratique, de nombreuses implémentations parfois générer des erreurs d'exécution de ce code, mais beaucoup ne le font pas. Elle dépend souvent de la nature du programme. Voici une illustration:Sur mon système, je reçois un SIGBUS de modification de la chaîne, mais la modification de la fonction fonctionne très bien. Cela est dû à la nature particulière de pointeurs de fonction, dont la valeur n'est pas toujours déterminé au moment de l'exécution si la valeur doit être stockée dans l'écriture de la mémoire.
Il n'est généralement pas sûr d'attraper un SIGBUS ou SIGSEGV en C++ et en faire une exception. Il est également très difficile de correctement
longjmp
d'un gestionnaire de signal — la moitié du code qui utilise ce modèle dans C est probablement incorrect. L'option la plus sûre est de laisser le programme de résilier immédiatement, ou si vous avez vraiment besoin de ce genre d'aide à partir de l'exécution, des travaux très soigneusement avec du code C de sorte que vous pouvez libérer les ressources appropriées dans une non —sortie C++ ne le fera pas parce quelongjmp
de ne pas appeler les destructeurs.Ou vous pouvez tout simplement passer à C# ou Java, qui ont tous deux exécutions qui le font pour vous et ramasseurs d'ordures que nettoyer après.
Hm, pourquoi dites-vous qu'il ne compile pas? Il compile correctement sur mon ordinateur, il n'a même pas de générer des avertissements avec
-Wall -Wextra
à l'aide declang
ougcc
(à l'exception de "unused parameter", qui est le bruit). La chaîne globale de typechar const[6]
et statique de la durée de stockage, ce qui signifie qu'il dispose de six octets de l'espace en permanence prévu pour elle. (Pensez-vous dechar *
?) Comme je l'ai expliqué dans le fil où vous avez demandé une référence, voir n1570 §6.7.3.6. Je ne peux pas toujours répondre à Débordement de Pile questions au cours de la journée, de sorte s'il vous plaît être patient.OriginalL'auteur Dietrich Epp
C'est spécifique du système d'exploitation. Le langage lui-même indique que ces comportements indéfinis.
Dans les systèmes POSIX votre programme peut attraper un
SIGSEGV
signal dans le cas d'une restriction de l'accès à la mémoire,SIGILL
dans le cas d'une instruction non valide ouSIGFPE
dans le cas du commerce illégal de l'opération de virgule flottante, par exemple une division par zéro.ne sont pas la plupart des grains de tuer le processus fautif après le gestionnaire de signal est exécuté de toute façon?
- vous fournir un boîtier de
not safe to do a normal return after catching a signal from a program error
?ce n'est pas le cas.
href="http://www.gnu.org/s/hello/manual/libc/Program-Error-Signals.html#Program-Error-Signals" >gnu.org/s/hello/manual/libc/... 4e alinéa. Intuitivement ce qui se passe si vous le retour de la
SIGFPE
gestionnaire dans la déclarationreturn 1/0;
? il ne fait pas de sens et est un comportement indéterminé.OriginalL'auteur Blagovest Buyukliev
En C des erreurs d'exécution, généralement de générer des signaux qui peuvent être traitées par les gestionnaires de signaux.
En C++ runtime erreurs peuvent également être jetés comme des exceptions qui peuvent être pris dans un bloc try/catch.
De continuer à un certain point, plutôt que de s'écraser, vous aurez besoin d'utiliser setjmp/longjmp dans les gestionnaires de signaux - il n'est pas sûr de revenir après la capture d'un signal à partir d'une erreur de programme
dépend de la définition de "runtime error" division par zéro n'est pas, mais des exceptions sont levées pour les autres erreurs, si non interceptée, encore stopper l'exécution du programme. Ce cours comme une erreur d'exécution dans mon livre...
sortir des limites d'un tableau, la modification d'un const objet, un déréférencement d'un pointeur vers une variable allé hors de portée, et vous dire que la PLUPART des choses que lancer des exceptions? 🙂
hmmmn, "généralement" peut avoir induit en erreur, édité
OriginalL'auteur tobyodavies
J'ai été tout à fait tort.
Tente de modifier un const qualifiés variable est en effet un comportement indéfini et, paraît-il, il y a quelques années. Il peut ou peut ne pas générer une erreur d'exécution; si c'est le cas ou pas dépend de la plate-forme.
n1570, qui est le comité de projet pour la prochaine itération de la norme C, donne la primauté à la section 6.7.3, comme @Dietrich Ppe patiemment souligné. Le libellé de cet article n'a probablement pas changé depuis C89.
Je suis extrêmement désolé pour prétendre le contraire; et, pour insultes envers les membres de ce groupe. Surtout Dietrich.
Maintenant, où puis-je trouver ces délicieux, libre-gamme, crow?
OriginalL'auteur Pete Wilson
Vous devez savoir cela, et il faut que votre exemple est mal considéré, mais il est intéressant de noter tout de même dans le cas où quelqu'un se fait de fausses idées:
En C, il n'y a pas une telle chose comme un
const int
(ouconst
autre chose) à moment de l'exécution;const
est purement une au moment de la compilation notion. Ainsi, il n'y a pas d'erreur run-time pour la modification d'unconst int
.const int
est "un comportement indéfini", selon le C spec. De nombreuses implémentations de l'attraper au moment de l'exécution et de soulever SIGBUS ou SIGSEGV.Ppe -- de référence, s'il vous plaît, si vous n'avez pas l'esprit.
c'était un exemple, et un mal choisi. Mais, depuis le comportement est indéfini, une erreur d'exécution se produire en théorie...
De n1570: §6.7.3.6: "Si une tentative est faite pour modifier un objet défini avec un const qualifiés de type par le biais de l'utilisation d'une lvalue avec les non-const-qualifiés de type, le comportement est indéfini."
Je ne pense pas que c'est une réponse.
OriginalL'auteur Pete Wilson
Si je comprends bien, les scénarios qui vous parlez, sont ceux qui (généralement) sont undefined en fonction de la langue.
Ces scénarios conduisent à des résultats imprévisibles, comme vous l'avez remarqué, ces résultats peuvent parfois inclure le programme continue et apparaissant à "travailler", ou il peut tomber en panne, ou nasale démons peuvent spontanément venu à l'existence.
Si vous voulez attraper l'utilisation de comportement indéfini, alors vous pouvez faire ce dans certaines situations, à l'aide d'outils.
Par exemple, Clôture Électrique est grande à révéler l'endroit où vous êtes l'écriture en mémoire que vous ne devriez pas être (mais ne pas l'activer dans les versions release!). Si cela fonctionne pour l'écriture de quelque chose dont
const
ness vous commentée de suite dépendra de ce que les optimisations ont été appliquées, il est possible que l'objet sera avoir les droits en écriture de la mémoire, et il sera physiquement impossible de déterminer que vous êtes en train de faire quelque chose de mal.Ce que vous n'allez pas pour obtenir une belle langue-couche d'exception. Puisque vous allez avoir à descendre les outils de route de toute façon, il suffit d'appliquer statique et dynamique des outils d'analyse du mieux que vous pouvez et profil. Il n'existe pas de moyen infaillible d'un coup à son tour sur "sainement m'informer de toute utilisation des Comportements Indéfinis".
OriginalL'auteur Lightness Races in Orbit