Câu trả lời thực sự ở đây là: Bạn không bao giờ có thể thực sự biết chắc chắn.
Ít nhất, đối với các trường hợp không cần thiết, bạn không thể chắc chắn mình đã nhận được tất cả. Hãy xem xét những điều sau đây từ bài viết của Wikipedia về mã không thể truy cập :
double x = sqrt(2);
if (x > 5)
{
doStuff();
}
Như Wikipedia lưu ý chính xác, một trình biên dịch thông minh có thể có thể bắt được một cái gì đó như thế này. Nhưng hãy xem xét một sửa đổi:
int y;
cin >> y;
double x = sqrt((double)y);
if (x != 0 && x < 1)
{
doStuff();
}
Trình biên dịch sẽ nắm bắt điều này? Có lẽ. Nhưng để làm điều đó, nó sẽ cần phải làm nhiều hơn là chạy sqrt
với giá trị vô hướng không đổi. Nó sẽ phải tìm ra rằng (double)y
sẽ luôn luôn là một số nguyên (dễ), và sau đó hiểu phạm vi toán học của sqrt
tập hợp các số nguyên (cứng). Một trình biên dịch rất tinh vi có thể có thể thực hiện điều này cho sqrt
hàm hoặc cho mọi hàm trong math.h hoặc cho bất kỳ hàm đầu vào cố định nào có miền mà nó có thể tìm ra. Điều này trở nên rất, rất phức tạp và sự phức tạp về cơ bản là vô hạn. Bạn có thể tiếp tục thêm các lớp tinh vi vào trình biên dịch của mình, nhưng sẽ luôn có cách để lẻn vào một số mã sẽ không thể truy cập được đối với bất kỳ bộ đầu vào cụ thể nào.
Và sau đó là các bộ đầu vào đơn giản là không bao giờ được nhập. Đầu vào sẽ không có ý nghĩa trong cuộc sống thực hoặc bị chặn bởi logic xác thực ở nơi khác. Không có cách nào để trình biên dịch biết về những điều đó.
Kết quả cuối cùng của việc này là trong khi các công cụ phần mềm mà những người khác đã đề cập là cực kỳ hữu ích, bạn sẽ không bao giờ biết chắc chắn rằng bạn đã nắm bắt mọi thứ trừ khi bạn đi qua mã theo cách thủ công sau đó. Ngay cả sau đó, bạn sẽ không bao giờ chắc chắn rằng bạn đã không bỏ lỡ bất cứ điều gì.
Giải pháp thực sự duy nhất, IMHO, là thận trọng nhất có thể, sử dụng tự động hóa theo ý của bạn, tái cấu trúc nơi bạn có thể và liên tục tìm cách cải thiện mã của mình. Tất nhiên, dù sao thì đó cũng là một ý tưởng tốt.