Bỏ qua để đến nội dung

Chuyển đổi ngầm định sang bool

C++ tự động chuyển đổi nhiều kiểu dữ liệu sang bool trong ngữ cảnh điều kiện (if, while, &&, ||…) - điều này tiện lợi nhưng cũng là nguồn gốc của nhiều lỗi tinh vi nếu không để ý.

Số 0 luôn là false, mọi số khác 0 đều là true

Phần tiêu đề “Số 0 luôn là false, mọi số khác 0 đều là true”
int code = -1;
if (code) { // -1 khác 0, nên đây là TRUE - có thể không phải điều bạn nghĩ!
std::cout << "Duoc coi la dung, du code la -1" << std::endl;
}

Đây là cạm bẫy phổ biến khi một hàm trả về mã lỗi (error code): quy ước thường là 0 nghĩa là “thành công”, khác 0 nghĩa là “có lỗi” - ngược lại với trực giác if (result):

int result = run_command(); // Giả sử: 0 = thành công, khác 0 = mã lỗi
if (result) { // SAI Ý ĐỊNH! Đoạn này chạy khi CÓ LỖI (result != 0), không phải khi thành công
std::cout << "Thanh cong?" << std::endl; // Nhầm lẫn logic
}
if (result == 0) { // ĐÚNG - kiểm tra tường minh, rõ ràng ý định
std::cout << "Thanh cong" << std::endl;
}

Con trỏ cũng chuyển đổi ngầm định sang bool

Phần tiêu đề “Con trỏ cũng chuyển đổi ngầm định sang bool”
int* ptr = get_pointer(); // Có thể trả về nullptr
if (ptr) { // Tương đương if (ptr != nullptr) - đây là cách viết phổ biến, không phải lỗi
std::cout << *ptr << std::endl;
}
if (!ptr) { // Tương đương if (ptr == nullptr)
std::cout << "Con tro rong" << std::endl;
}

Cách viết if (ptr) là hợp lệ và phổ biến, nhưng cần chắc chắn ptr thực sự mang ý nghĩa “có tồn tại hay không”, không phải một con trỏ luôn được kỳ vọng hợp lệ (trường hợp đó nên dùng assert hoặc kiểm tra tường minh hơn).

#include <memory>
std::unique_ptr<int> ptr = std::make_unique<int>(42);
if (ptr) { // Kiểm tra ptr có đang quản lý một đối tượng hay không
std::cout << *ptr << std::endl;
}

Cạm bẫy: nhầm === càng nguy hiểm hơn với chuyển đổi ngầm định

Phần tiêu đề “Cạm bẫy: nhầm = và == càng nguy hiểm hơn với chuyển đổi ngầm định”
int flag = 0;
if (flag = 5) { // GÁN, không phải so sánh - 5 khác 0 nên LUÔN đúng!
std::cout << "Luon chay vao day" << std::endl; // Lỗi logic nghiêm trọng
}

Đã đề cập ở bài “Thứ tự ưu tiên toán tử” - kết hợp với chuyển đổi ngầm định sang bool, lỗi gõ nhầm =/== trở nên đặc biệt khó phát hiện vì code vẫn biên dịch và “chạy được”.

C++ tự động chuyển 0/con trỏ null thành false, mọi giá trị khác thành true trong ngữ cảnh điều kiện.

  • Cẩn thận với các hàm trả về mã lỗi kiểu C (0 = thành công) - if (result) dễ bị hiểu ngược ý định
  • Luôn viết điều kiện tường minh (if (result == 0)) khi ý nghĩa của giá trị số không hiển nhiên là true/false
  • Bật cảnh báo trình biên dịch để bắt lỗi gõ nhầm = thành ==