Biến chưa khởi tạo (Uninitialized Variable)
Vấn đề
Phần tiêu đề “Vấn đề”Khác với nhiều ngôn ngữ tự động gán giá trị mặc định (0, None…), một biến cục bộ trong C++ không được khởi tạo tự động - nó chứa bất kỳ giá trị nào đang có sẵn trong vùng nhớ đó (giá trị “rác”):
int x; // Chưa khởi tạostd::cout << x << std::endl; // In ra một giá trị NGẪU NHIÊN, không phải 0!Nguy hiểm hơn: dùng trong điều kiện hoặc phép toán
Phần tiêu đề “Nguy hiểm hơn: dùng trong điều kiện hoặc phép toán”int count;if (count > 0) { // Kết quả không dự đoán được - phụ thuộc vào giá trị rác std::cout << "Co gia tri duong" << std::endl;}
int total;for (int i = 0; i < 5; i++) { total += i; // total bắt đầu từ giá trị rác, không phải 0!}std::cout << total << std::endl; // Kết quả sai, không thể đoán trướcVì sao C++ không tự khởi tạo?
Phần tiêu đề “Vì sao C++ không tự khởi tạo?”Đây là quyết định thiết kế có chủ đích: khởi tạo mọi biến tốn thời gian, và C++ ưu tiên hiệu năng tối đa - triết lý “không trả tiền cho thứ bạn không dùng”. Nếu bạn chắc chắn sẽ gán giá trị ngay sau đó, việc khởi tạo mặc định là lãng phí.
Ngoại lệ: biến toàn cục và static được khởi tạo về 0
Phần tiêu đề “Ngoại lệ: biến toàn cục và static được khởi tạo về 0”int global_var; // Biến TOÀN CỤC - tự động là 0static int static_var; // Biến static cũng vậy
int main() { int local_var; // Biến CỤC BỘ - KHÔNG tự động là 0, chứa giá trị rác! std::cout << global_var << std::endl; // 0 std::cout << static_var << std::endl; // 0 // std::cout << local_var << std::endl; // Giá trị không xác định return 0;}Giải pháp: luôn khởi tạo khi khai báo
Phần tiêu đề “Giải pháp: luôn khởi tạo khi khai báo”int x = 0; // Khởi tạo tường minhint y{}; // Cú pháp uniform initialization - cũng cho ra 0std::string name{}; // Chuỗi rỗngstd::vector<int> v{}; // Vector rỗng
int total = 0; // Luôn khởi tạo biến tích lũy trước vòng lặpfor (int i = 0; i < 5; i++) { total += i;}Nhiều trình biên dịch hỗ trợ cảnh báo (-Wall -Wuninitialized với g++/clang) giúp phát hiện các biến có khả năng dùng trước khi khởi tạo - nên luôn bật các cờ cảnh báo này khi biên dịch.
Tóm tắt
Phần tiêu đề “Tóm tắt”Biến cục bộ chưa khởi tạo chứa giá trị rác, không phải
0như nhiều người lầm tưởng.
- Biến toàn cục và
staticthì khác - luôn tự động là0- Luôn khởi tạo biến ngay khi khai báo (
int x = 0;hoặcint x{};)- Bật cờ cảnh báo trình biên dịch (
-Wall -Wuninitialized) để bắt lỗi này sớm