Câu trả lời:
Một hack tôi đã thấy xung quanh là sử dụng &&
toán tử. Vì một con trỏ "là đúng" nếu nó không có giá trị, bạn có thể thực hiện các thao tác sau mà không thay đổi điều kiện:
assert(a == b && "A is not equal to B");
Vì assert
hiển thị điều kiện không thành công, nó cũng sẽ hiển thị thông báo của bạn. Nếu nó không đủ, bạn có thể viết myAssert
hàm hoặc macro của riêng bạn sẽ hiển thị bất cứ thứ gì bạn muốn.
assert(("A must be equal to B", a == b));
assert(a == b && "A (" << A << ") is not equal to B (" << B << ")");
printf
trả về giá trị khác không nếu nó in bất cứ thứ gì, vì vậy bạn có thể làm một cái gì đó như thế assert(a == b && printf("a (%i) is not equal to b (%i)", a, b))
, mặc dù tại thời điểm đó có lẽ bạn nên viết trình bao bọc khẳng định của riêng bạn.
Một tùy chọn khác là đảo ngược toán hạng và sử dụng toán tử dấu phẩy. Bạn cần thêm dấu ngoặc đơn để dấu phẩy không được coi là dấu phân cách giữa các đối số:
assert(("A must be equal to B", a == b));
(điều này đã được sao chép từ các ý kiến trên, để nhìn rõ hơn)
#define m_assert(expr, msg) assert(( (void)(msg), (expr) ))
Đây là phiên bản macro khẳng định của tôi, chấp nhận thông báo và in mọi thứ ra một cách rõ ràng:
#include <iostream>
#ifndef NDEBUG
# define M_Assert(Expr, Msg) \
__M_Assert(#Expr, Expr, __FILE__, __LINE__, Msg)
#else
# define M_Assert(Expr, Msg) ;
#endif
void __M_Assert(const char* expr_str, bool expr, const char* file, int line, const char* msg)
{
if (!expr)
{
std::cerr << "Assert failed:\t" << msg << "\n"
<< "Expected:\t" << expr_str << "\n"
<< "Source:\t\t" << file << ", line " << line << "\n";
abort();
}
}
Bây giờ, bạn có thể sử dụng này
M_Assert(ptr != nullptr, "MyFunction: requires non-null argument");
Và trong trường hợp thất bại, bạn sẽ nhận được một tin nhắn như thế này:
Khẳng định thất bại: MyFunction: yêu cầu đối số không null
Dự kiến: ptr! = Nullptr
Nguồn: C: \ MyProject \ src.cpp, dòng 22
Đẹp và sạch sẽ, hãy sử dụng nó trong mã của bạn =)
x == y
. Sau đó, Expr sẽ mở rộng vào if( !(x == y))
và đây là nơi kiểm tra điều kiện và #Expr sẽ mở rộng thành chuỗi ký tự "x == y"
, sau đó chúng tôi đưa vào thông báo lỗi.
BOOST_ASSERT_MSG(expre, msg)
http://www.boost.org/doc/libs/1_51_0/libs/utility/assert.html
Bạn có thể sử dụng trực tiếp hoặc sao chép mã của Boost. Cũng lưu ý Boost assert chỉ là tiêu đề, vì vậy bạn chỉ có thể lấy tệp đó nếu bạn không muốn cài đặt tất cả Boost.
Khi câu trả lời của zneak làm xáo trộn phần nào mã, một cách tiếp cận tốt hơn là chỉ bình luận chuỗi văn bản bạn đang nói đến. I E.:
assert(a == b); // A must be equal to B
Vì người đọc lỗi xác nhận sẽ tìm kiếm tệp và dòng dù sao từ thông báo lỗi, họ sẽ thấy giải thích đầy đủ ở đây.
Bởi vì, vào cuối ngày, điều này:
assert(number_of_frames != 0); // Has frames to update
đọc tốt hơn thế này:
assert(number_of_frames != 0 && "Has frames to update");
về mặt phân tích cú pháp của con người tức là. khả năng đọc. Cũng không phải là một ngôn ngữ hack.
khẳng định là sự kết hợp vĩ mô / chức năng. bạn có thể xác định vĩ mô của riêng bạn / chức năng, sử dụng __FILE__
, __BASE_FILE__
, __LINE__
vv, với chức năng riêng của mình mà phải mất một thông báo tùy chỉnh
Đối với vc, thêm mã sau vào assert.h,
#define assert2(_Expression, _Msg) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Msg), _CRT_WIDE(__FILE__), __LINE__), 0) )