Answers:
我所见过的一个hack是使用&&
运算符。由于指针“为真”(如果非空),因此可以执行以下操作而无需更改条件:
assert(a == b && "A is not equal to B");
由于assert
显示失败的情况,因此也会显示您的消息。如果还不够,您可以编写自己的myAssert
函数或宏,以显示所需的内容。
assert(("A must be equal to B", a == b));
assert(a == b && "A (" << A << ") is not equal to B (" << B << ")");
printf
如果打印了任何内容,则返回非零值,因此您可以执行类似的操作assert(a == b && printf("a (%i) is not equal to b (%i)", a, b))
,尽管此时您可能应该编写自己的断言包装器。
另一种选择是反转操作数并使用逗号运算符。您需要额外的括号,因此逗号不会被视为参数之间的定界符:
assert(("A must be equal to B", a == b));
(这是从上面的注释中复制的,以提高可见性)
#define m_assert(expr, msg) assert(( (void)(msg), (expr) ))
这是我的assert宏版本,它接受消息并以清晰的方式打印出所有内容:
#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();
}
}
现在,您可以使用此
M_Assert(ptr != nullptr, "MyFunction: requires non-null argument");
如果发生故障,您将收到以下消息:
断言失败:MyFunction:需要非空参数
预期:ptr!= nullptr
来源:C:\ MyProject \ src.cpp,第22行
干净整洁,随时在您的代码中使用它=)
x == y
。然后Expr将扩展为if( !(x == y))
,这是检查条件的地方,并且#Expr将扩展为字符串文字"x == y"
,然后将其放入错误消息中。
BOOST_ASSERT_MSG(expre, msg)
http://www.boost.org/doc/libs/1_51_0/libs/utility/assert.html
您可以直接使用它,也可以复制Boost的代码。还要注意,Boost assert仅是标头,因此,如果您不想安装所有Boost,就可以只抓取一个文件。
当zneak的答案使代码有些复杂时,一种更好的方法是仅注释您正在谈论的字符串文本。即:
assert(a == b); // A must be equal to B
由于断言错误的阅读者无论如何都会从错误消息中查找文件并进行换行,因此他们将在此处看到完整的说明。
因为在一天结束时,这是:
assert(number_of_frames != 0); // Has frames to update
读起来比这更好:
assert(number_of_frames != 0 && "Has frames to update");
就代码的人工解析而言 可读性。也不是语言黑客。
assert是宏/功能的组合。你可以定义自己的宏/功能,使用__FILE__
,__BASE_FILE__
,__LINE__
等,用自己的函数,它的自定义消息