2012-09-24 45 views
9

Tôi không thể tìm thấy một tuyên bố rõ ràng về ngữ nghĩa của Q_ASSERT trong bản phát hành bản phát hành. Nếu không có kiểm tra xác nhận, thì biểu thức được khẳng định được đánh giá là gì?Q_ASSERT phát hành ngữ nghĩa xây dựng

Xét đoạn mã sau

Q_ASSERT(do_something_report_false_if_failed()); 

Will do_something_report_false_if_failed() chạy theo tất cả Qt xây dựng cấu hình tiềm năng? nó sẽ được an toàn hơn (mặc dù một chút dài dòng hơn và ít có thể đọc được) để làm điều này thay vì:

bool is_ok = do_something_report_false_if_failed(); 
Q_ASSERT(is_ok) 

Cách tiếp cận thứ hai có nhược điểm là khẳng định thất bại ít tiết, nhưng có lẽ nó cho thấy rõ ràng hơn rằng tuyên bố là Thực thi?

Trả lời

15

Biểu thức bên trong Q_ASSERT sẽ không được đánh giá trong cấu hình không gỡ lỗi.

Hãy xem xét mã nguồn bên dưới từ Qt repo.

#if !defined(Q_ASSERT) 
# ifndef QT_NO_DEBUG 
# define Q_ASSERT(cond) ((!(cond)) ? qt_assert(#cond,__FILE__,__LINE__) : qt_noop()) 
# else 
# define Q_ASSERT(cond) qt_noop()  
# endif  
#endif 

Nếu QT_NO_DEBUG được xác định, sau đó toàn bộ Q_ASSERT tuyên bố được thay thế bằng một qt_noop(), do đó loại bỏ bất kỳ biểu hiện rằng nó trước đây chứa.

Không bao giờ dựa vào bất kỳ tác dụng phụ nào được tạo bởi biểu thức bên trong tuyên bố Q_ASSERT. Về mặt kỹ thuật, vẫn có thể đảm bảo rằng QT_NO_DEBUG không được xác định trong cấu hình xây dựng cụ thể, nhưng đây không phải là một ý tưởng hay.

+0

Đó chính xác là tình huống tương tự như với macro 'assert' và' NDEBUG' thông thường. –

14

này có vẻ là khác nhau trong Qt5.5 (nhưng không sớm - xem Qt5.4):

#if !defined(Q_ASSERT) 
# if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS) 
# define Q_ASSERT(cond) do { } while ((false) && (cond)) 
# else 
# define Q_ASSERT(cond) ((!(cond)) ? qt_assert(#cond,__FILE__,__LINE__) : qt_noop()) 
# endif 
#endif 

Tôi bây giờ nhận được rất nhiều "cảnh báo C4127: biểu thức điều kiện là hằng số" trong Visual Studio 2013.

cập nhật: Qt5.5 release notes nói:

Q_ASSERT bây giờ sẽ mở rộng điều kiện ngay cả trong chế độ phát hành khi xác nhận bị tắt, mặc dù trong đường dẫn mã không thể truy cập. Điều này giải quyết cảnh báo trình biên dịch về các biến và chức năng là không được sử dụng trong chế độ phát hành vì chúng chỉ được sử dụng trong các xác nhận. Thật không may, các codebases ẩn các chức năng và biến số thông qua #ifndef sẽ cần phải loại bỏ các điều kiện để biên dịch với Qt 5.5.

+0

Xác định lại Q_ASSERT và Q_ASSERT_X quay lại noop giúp – user2846246

+2

Đây là thay đổi trong gerrit: https://codereview.qt-project.org/#/c/94460/3 – Uflex

+0

Tôi gặp vấn đề tương tự. Điều này có được sửa trong các phiên bản Qt> 5.5 không? – Knitschi

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