Khi giá trị vượt quá phạm vi biểu diễn của kiểubuiltin, hành vi phụ thuộc vào kiểu có dấu (signed) hay không dấu (unsigned).
1. Kiểu có dấu (signed) - Undefined Behavior
#include <iostream>
#include <climits>
using namespace std;
int main() {
int x = INT_MAX; // 2147483647
cout << x+1 << endl; // UNDEFINED BEHAVIOR!
// Thường thấy: -2147483648 (tràn thành số âm)
return 0;
}
C++ Standard: Signed integer overflow là Undefined Behavior. Compiler có quyền tối ưu hóa giả định nó không xảy ra.
2. Kiểu không dấu (unsigned) - Wrap-around xác định
#include <iostream>
using namespace std;
int main() {
unsigned int u = UINT_MAX; // 4294967295
cout << u+1 << endl; // 0 (quay vòng modulo 2^32)
unsigned char c = 255;
cout << int(c+1) << endl; // 0
return 0;
}
Unsigned overflow được định nghĩa: tính modulo 2^N.
3. Ví dụ vòng lặp vô tận do overflow
// Sai: char có thể signed hoặc unsigned tùy implementation for (char c = 0; c <= 200; c++) cout << int(c) << ' '; // Nếu char signed (max 127): c=127 -> c++ = -128 -> -128 <= 200 -> VÔ TẬN // Đúng: dùng int cho biến đếm for (int i = 0; i <= 200; i++) cout << i << ' ';
4. Bool overflow
bool b = true; for (b = true; b <= 6; b++) cout << b; // In "111111..." vô tận // true = 1, ++true vẫn là true (1)
Khuyến nghị
- Dùng
intcho biến đếm, chỉ số mảng. - Dùng
unsignedchỉ khi cần ngữ nghĩa bitwise hoặc modulo. - Kiểm tra tràn trước khi thực hiện phép toán (ví dụ:
if (a > INT_MAX - b)). - Bật cảnh báo compiler:
-Woverflow -Wsign-conversion(GCC/Clang).