2010-03-08 4 views
10

Есть ли общий способ проверки переполнения или недотока заданного типа данных (uint32, int и т. Д.)?Проверка недостаточности/переполнения в C++?

Я делаю что-то вроде этого:

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

При печати после нескольких итераций, он отображает большое количество, как: 4294963846.

+0

[Как обнаружить переполнение целых чисел в C/C++?] (http://stackoverflow.com/q/199333/995714) –

ответ

9

Чтобы проверить над/сгущенного в арифметике проверить результат по сравнению с исходными значениями.

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

для вашей конкретной проверки будет:

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

Спасибо. На данный момент это работает нормально ... – Legend

+0

- это тот факт, что в случае переполнения ответ всегда будет подписанным (отрицательное целое число)? – Faizan

+0

Переполнение целых чисел без знака никогда не будет подписано, скорее это будет меньшее целое число без знака, чем любое из исходных значений. –

4

Я думаю, если бы я хотел сделать, что я хотел бы сделать класс, который имитирует тип данных, и сделать это вручную (который будет медленным Я бы себе)

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; 

это может быть более сложным, чем это, возможно, придется свернуть с помощью определения вместо ЬурейеЕ ...

Я сделал аналогичную вещь с указателями, чтобы проверить, где была выписана память. очень медленно, но обнаружил, что память была повреждена.

+0

Ищет более простой подход ... Но в любом случае спасибо за это .. – Legend

+0

Существует версия этого [называемого SafeInt] (http: //safeint.codeplex .com /), о которых я узнал сегодня вечером. Вероятно, неплохо бы использовать что-то подобное большую часть времени, просто не в критическом для производительности коде. – HostileFork

2

Cert имеет хорошую ссылку для signed integer overflow, которая является неопределенным поведением и unsigned wrapping, которая не является и охватывает все операторы.

Документ содержит следующий код проверки для неподписанной обертки в вычитании с помощью предварительных условий заключается в следующем:

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

и постусловия:

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

Если вы gcc 5 вы можете использовать __builtin_sub_overflow :

__builtin_sub_overflow(ui_a, ui_b, &udiff)