2010-09-07 31 views
5

Trong khi xem xét codebase Visual C++ tôi tìm thấy một điều kỳ lạ sau đây. Một khẳng định thời gian chạy (mà là kiểm tra điều kiện và ném một ngoại lệ nếu tình trạng này bị vi phạm) được sử dụng trong trường hợp khi điều kiện này có thể được đánh giá ở thời gian biên dịch:Bất kỳ lý do nào để sử dụng xác nhận thời gian chạy thay vì xác nhận thời gian biên dịch?

assert(sizeof(SomeType) == sizeof(SomeOtherType)); 

rõ trình biên dịch sẽ đánh giá điều kiện và thay thế mã đó sẽ có hiệu quả là một trong hai

assert(true); 

mà không làm gì hoặc

assert(false); 

mà ném một ngoại lệ mỗi khi điều khiển đi qua dòng đó.

IMO một khẳng định thời gian biên dịch nên đã được sử dụng thay vì những lý do sau đây:

  • nó sẽ phơi bày những vi phạm điều kiện trước đó - tại thời gian biên dịch - và
  • nó sẽ cho phép bụi (do đó nhanh hơn và nhỏ hơn) mã máy được phát ra

Dường như xác nhận thời gian biên dịch là điều đúng duy nhất. Có lý do nào có thể để thích một xác nhận thời gian chạy ở đây không?

+3

Có vẻ như một WTF cho tôi. – egrunin

+0

'khẳng định' thường không ném ngoại lệ mà là hủy bỏ chương trình. –

+0

Tính đến thời điểm này, không có xác nhận biên dịch chuẩn nào. Thực tế đó là khá quan trọng, đặc biệt là ở các cơ sở mã cũ hơn. –

Trả lời

15

Không có lý do gì để chọn xác nhận thời gian chạy tại đây. Bạn nên sử dụng các lỗi biên dịch thời gian hơn các lỗi thời gian chạy vì vậy không bao giờ có một lý do, được cung cấp tùy chọn giữa hai, để chọn một xác nhận thời gian chạy.

Tuy nhiên, nếu khẳng định tĩnh không phải là một tùy chọn (không biết khái niệm về xác nhận tĩnh, không biết cách tạo một cái và không có sẵn, hoặc biết cách tạo một không có thời gian), một khẳng định thời gian chạy là điều tốt nhất tiếp theo.

Với C++ 0x, tính năng được xây dựng trong static_assert sẽ kết thúc tất cả lý do để sử dụng xác nhận thời gian chạy, nơi xác nhận thời gian biên dịch sẽ hoạt động.

4

Chúng tôi không thể nói mà không có ngữ cảnh. Trong mã mẫu, một số nhánh có thể không thể truy cập được đối với một số instantiations. Một xác nhận thời gian biên dịch sẽ không phù hợp, vì điều đó làm cho toàn bộ hàm bị biến dạng. An assert(<type-dependent expression>) thì không.

Ví dụ:

template <typename T> void foo(T t) 
{ 
    if (t < 0) { 
    assert(std::numeric_limits<T>::min() < 0); 
    T u = t - std::numeric_limits<T>::min(); 
    } 
} 

Xác nhận không thể chuyển thành xác nhận tĩnh, mặc dù xác nhận thời gian chạy không bao giờ thất bại.

+0

Tại sao nó không thể được tạo thành một 'static_assert'? – GManNickG

+0

'assert (std :: numeric_limits :: min <0);' luôn thất bại, bất kể T. – usta

+0

@usta: bạn có nhận xét về việc thiếu cuộc gọi chức năng không? @MSalters: Tôi nghĩ bạn muốn 'min()' –

Các vấn đề liên quan