2010-03-08 40 views
10

Có cách tổng quát nào để kiểm tra tình trạng tràn hoặc tràn của một kiểu dữ liệu nhất định (uint32, int, v.v.) không?Kiểm tra tràn/tràn trong C++?

Tôi đang làm một cái gì đó như thế này:

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

Khi tôi in một sau khi một số lần lặp lại, nó sẽ hiển thị một số lượng lớn như: 4294963846.

+0

[Cách phát hiện tràn số nguyên trong C/C++?] (http://stackoverflow.com/q/199333/995714) –

Trả lời

9

Để kiểm tra cho hơn/underflow trong số học kiểm tra kết quả so với giá trị ban đầu.

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

Đối cụ thể của bạn kiểm tra sẽ là:

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

Cảm ơn. Điều này dường như làm việc tốt cho bây giờ ... – Legend

+0

là một thực tế là trong trường hợp tràn câu trả lời sẽ luôn luôn là một chữ ký (số nguyên âm)? – Faizan

+0

Tràn các số nguyên chưa ký sẽ không bao giờ được ký, thay vào đó nó sẽ là một số nguyên không dấu nhỏ hơn một trong các giá trị ban đầu. –

4

Tôi đoán nếu tôi muốn làm điều đó tôi sẽ làm một lớp mô phỏng các kiểu dữ liệu, và làm điều đó bằng tay (mà sẽ chậm tôi sẽ tưởng tượng)

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; 

nó có thể có nhiều khó khăn hơn thế, bạn có thể phải gió lên sử dụng một định nghĩa thay vì một typedef ...

Tôi đã làm một điều tương tự với con trỏ để kiểm tra nơi bộ nhớ đã được viết ra bên ngoài giới hạn. rất chậm nhưng đã tìm thấy nơi bộ nhớ bị hỏng

+0

Đã tìm kiếm một cách tiếp cận đơn giản hơn ... Nhưng trong mọi trường hợp, cảm ơn cho điều này .. – Legend

+0

Có phiên bản của [SafeInt] này (http: //safeint.codeplex) .com /) mà tôi đã học về tối nay. Nó có lẽ không phải là một ý tưởng tồi để sử dụng một cái gì đó như vậy hầu hết thời gian, chỉ cần không có trong mã hiệu suất quan trọng. – HostileFork

2

Chứng chỉ có một tham chiếu tốt cho cả signed integer overflow là hành vi không xác định và unsigned wrapping và chúng không bao gồm tất cả các toán tử.

Tài liệu này cung cấp mã kiểm tra sau cho gói unsigned trong trừ sử dụng điều kiện tiên quyết là như sau:

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

và với hậu điều kiện:

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

Nếu bạn là gcc 5 bạn có thể sử dụng __builtin_sub_overflow :

__builtin_sub_overflow(ui_a, ui_b, &udiff)