2010-03-08 10 views
10

¿Existe una forma general de verificar si hay un desbordamiento o un subdesbordamiento de un tipo de datos dado (uint32, int, etc.)?Comprobación de subdesbordamiento/desbordamiento en C++?

que estoy haciendo algo como esto:

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

Al imprimir una después de algunas iteraciones, se muestra como un gran número: 4294963846.

+0

[Cómo detectar un desbordamiento entero en C/C++?] (http://stackoverflow.com/q/199333/995714) –

Respuesta

9

Para comprobar si hay más/desbordamiento en aritmética comprobar el resultado en comparación con los valores originales.

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

Para su específica la comprobación sería:

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

Gracias. Esto parece funcionar bien por ahora ... – Legend

+0

¿Es este el hecho de que en caso de desbordamiento, la respuesta siempre será un signo (número entero negativo)? – Faizan

+0

El desbordamiento de enteros sin signo nunca se firmará, sino que será un número entero sin signo más pequeño que cualquiera de los valores originales. –

4

supongo que si lo que quería hacer que me gustaría hacer una clase que simula el tipo de datos, y hacerlo de forma manual (que sería lenta me imagino)

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; 

puede ser más complicado que eso, puede que tenga que terminar usando un lugar de definir un typedef ...

Hice algo similar con los punteros para verificar dónde se estaba grabando la memoria al costado de los límites. muy lento pero encontró donde se corrompía la memoria

+0

Estaba buscando un enfoque más simple ... Pero en cualquier caso, gracias por esto .. – Legend

+0

Hay una versión de esto [llamada SafeInt] (http: //safeint.codeplex .com /) que aprendí esta noche. Probablemente no sea una mala idea usar algo así la mayor parte del tiempo, simplemente no en el código de rendimiento crítico. – HostileFork

2

Cert tiene una buena referencia tanto para signed integer overflow que es el comportamiento indefinido y unsigned wrapping que no lo es y cubren todos los operadores.

El documento proporciona el siguiente código de verificación para envolver sin firmar en la resta usando condiciones previas es el siguiente:

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; 
    } 
    /* ... */ 
} 

y con post-condiciones:

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

Si usted es gcc 5 se puede utilizar __builtin_sub_overflow :

__builtin_sub_overflow(ui_a, ui_b, &udiff) 
Cuestiones relacionadas