2010-03-08 13 views
10

Existe-t-il un moyen général de vérifier un débordement ou un sous-dépassement d'un type de données donné (uint32, int, etc.)?Vérification du dépassement de capacité/débordement en C++?

que je fais quelque chose comme ceci:

uint32 a,b,c; 
... //initialize a,b,c 
if(b < c) { 
    a -= (c - b) 
} 

Lorsque j'imprime un après quelques itérations, il affiche un grand nombre comme: 4294963846.

+0

[Comment détecter un débordement d'entier en C/C++?] (http://stackoverflow.com/q/199333/995714) –

Répondre

9

Pour vérifier plus haut/bas en arithmétique vérifier le résultat par rapport aux valeurs d'origine.

uint32 a,b; 
//assign values 
uint32 result = a + b; 
if (result < a) { 
    //Overflow 
} 

Pour votre propre chèque serait:

if (a > (c-b)) { 
    //Underflow 
} 
+0

Merci. Cela semble bien fonctionner pour l'instant ... – Legend

+0

est-ce le fait qu'en cas de débordement la réponse sera toujours un entier signé (nombre entier négatif)? – Faizan

+0

Le débordement d'entiers non signés ne sera jamais signé, mais plutôt un entier non signé plus petit que l'une des valeurs d'origine. –

4

Je suppose que si je voulais faire que je ferais une classe qui simule le type de données, et le faire manuellement (ce qui serait lent J'imagine)

class MyInt 
{ 
    int val; 
    MyInt(const int&nval){ val = nval;} // cast from int 
    operator int(){return val;} // cast to int 

    // then just overload ALL the operators... putting your check in 
}; 

//typedef int sint32; 
typedef MyInt sint32; 

il peut être plus difficile que cela, vous pourriez avoir à liquider en utilisant une définition au lieu d'un typedef ...

J'ai fait une chose similaire avec des pointeurs pour vérifier où la mémoire était écrite en dehors des limites. très lent, mais n'a pas trouvé où la mémoire était corrompue

+0

Cherchait une approche plus simple ... Mais en tout cas, merci pour cela .. – Legend

+0

Il existe une version de ce [appelé SafeInt] (http: //safeint.codeplex .com /) que j'ai appris sur ce soir. Ce n'est probablement pas une mauvaise idée d'utiliser quelque chose comme ça la plupart du temps, mais pas dans le code critique de performance. – HostileFork

2

Cert a une bonne référence pour les signed integer overflow qui est un comportement non défini et unsigned wrapping qui ne sont pas et ils couvrent tous les opérateurs.

Le document fournit le code de vérification suivant pour l'emballage non signé soustraction à l'aide des conditions préalables est comme suit:

void func(unsigned int ui_a, unsigned int ui_b) { 
    unsigned int udiff; 
    if (ui_a < ui_b){ 
    /* Handle error */ 
    } else { 
    udiff = ui_a - ui_b; 
    } 
    /* ... */ 
} 

et post-conditions:

void func(unsigned int ui_a, unsigned int ui_b) { 
    unsigned int udiff = ui_a - ui_b; 
    if (udiff > ui_a) { 
    /* Handle error */ 
    } 
    /* ... */ 
} 

Si vous êtes gcc 5 vous pouvez utiliser __builtin_sub_overflow :

__builtin_sub_overflow(ui_a, ui_b, &udiff) 
Questions connexes