2009-09-22 5 views
4

Je me demande simplement s'il existe un moyen pratique de détecter si un dépassement survient avec n'importe quelle variable d'un type de données par défaut utilisé dans un programme C++ pendant l'exécution? Par commodité, je veux dire pas besoin d'écrire du code pour suivre chaque variable si elle est dans la gamme de son type de données chaque fois que sa valeur change. Ou s'il est impossible d'y parvenir, comment feriez-vous?Comment détecter un débordement en C++?

Par exemple,

float f1=FLT_MAX+1; 
cout << f1 << endl; 

ne donne pas d'erreur ou d'avertissement soit compilation avec "gcc -W -Wall" ou en cours d'exécution.

Merci pour votre intérêt!

+0

Je spéculer que vous pourriez possible mettre en place un gestionnaire d'interruption pour le faire? En supposant que le débordement génère réellement une interruption. Comme vous pouvez le voir, je ne fais que spéculer ici, l'ajoutant ainsi comme un commentaire plutôt que comme une réponse. – korona

+3

n'est-il pas préférable d'écrire du code qui empêche (ou rend plus difficile de se produire) les débordements plutôt que d'essayer de l'attraper en train de se produire? Je ne fais que jeter la pensée. – Jay

+0

@Jay: pas nécessairement. Surtout en virgule flottante, il existe des classes d'algorithmes pour lesquelles le débordement est très, très rare, et la dépense de calcul supplémentaire pour l'empêcher complètement est très grande. Dans une situation de performance critique, vous pouvez utiliser l'algorithme rapide qui n'empêche pas le débordement et rejouer le calcul en un million pour lequel le dépassement se produit en utilisant l'algorithme prudent et lent qui empêche le débordement. –

Répondre

6

Pensez à utiliser boosts numeric conversion qui vous donne negative_overflow et positive_overflow exceptions (examples).

+0

+1. non seulement cela semble être une bonne solution, mais j'ai appris que "débordement négatif" et "débordement" ne sont pas la même chose ... idiot moi. – rmeador

2

Dans les situations où j'ai besoin de détecter un débordement, j'utilise SafeInt<T>. C'est une solution multiplateforme qui jette une exception dans les situations de débordement.

SafeInt<float> f1 = FLT_MAX; 
f1 += 1; // throws 

Il est disponible sur CodePlex

4

Votre exemple ne déborde pas réellement dans l'environnement à virgule flottante par défaut dans un système conforme à la norme IEEE-754.

Sur un tel système, où float est un nombre à virgule flottante binaire de 32 bits, FLT_MAX est 0x1.fffffep127 en notation à virgule flottante hexadécimale C99. L'écrire comme un entier dans l'hexagone, il ressemble à ceci:

0xffffff00000000000000000000000000 

Ajout d'un (sans arrondi, comme si les valeurs sont des nombres entiers de précision arbitraire), donne:

0xffffff00000000000000000000000001 

Mais la valeur par défaut environnement en virgule flottante sur un système conforme à la norme IEEE-754, une valeur comprise entre

0xfffffe80000000000000000000000000 

et

0xffffff80000000000000000000000000 

(qui inclut la valeur que vous avez spécifiée) est arrondie à FLT_MAX. Aucun débordement n'a lieu.

De plus, votre expression (FLT_MAX + 1) est susceptible d'être évaluée au moment de la compilation, et non de l'exécution, car elle n'a aucun effet secondaire visible pour votre programme.

2

Autrefois, lorsque je développais C++ (199x), nous utilisions un outil appelé Purify. À l'époque, c'était un outil qui instrumentait le code objet et enregistrait tout «mauvais» lors d'un test. J'ai fait un rapide Google et je ne suis pas tout à fait sûr si elle existe toujours. Pour autant que je sache aujourd'hui, il existe plusieurs outils open source qui font plus ou moins la même chose. Commander clôture électrique et valgrind.

+2

Purifier existe; il fait maintenant partie du jeu d'outils [Rational] (http://www-01.ibm.com/software/awdtools/purify/) d'IBM. –