有没有办法添加或编辑断言抛出的消息?我想使用像
这样的东西assert(a == b, "A must be equal to B");
然后,编译器添加行,时间等等......
有可能吗?
答案 0 :(得分:199)
我见过的黑客是使用&&
运算符。如果指针“为真”,如果它是非空的,你可以在不改变条件的情况下执行以下操作:
assert(a == b && "A is not equal to B");
由于assert
显示失败的情况,它也会显示您的消息。如果还不够,您可以编写自己的myAssert
函数或宏来显示您想要的任何内容。
答案 1 :(得分:34)
另一种选择是反转操作数并使用逗号运算符。您需要额外的括号,因此逗号不会被视为参数之间的分隔符:
assert(("A must be equal to B", a == b));
(这是从上面的评论中复制的,以获得更好的可见性)
答案 2 :(得分:18)
BOOST_ASSERT_MSG(expre, msg)
http://www.boost.org/doc/libs/1_51_0/libs/utility/assert.html
您可以直接使用它或复制Boost的代码。另请注意,Boost断言仅是标头,因此如果您不想安装所有Boost,则可以抓取该单个文件。
答案 3 :(得分:18)
这是我的断言宏版本,它接受消息并以清晰的方式打印出所有内容:
#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行
干净整洁,随意在你的代码中使用它=)
答案 4 :(得分:7)
由于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");
就人类解析代码而言。可读性。也不是语言黑客。
答案 5 :(得分:1)
断言是一个宏/函数组合。你可以使用__FILE__
,__BASE_FILE__
,__LINE__
等定义自己的宏/函数,使用自己的函数来获取自定义消息
答案 6 :(得分:0)
为什么没有人提到最干净的解决方案?
bool AMustBeEqualToB = (a == b);
assert(AMustBeEqualToB);
答案 7 :(得分:0)
您也可以只编写自己的自定义断言函数。一个非常简单的例子:
bool print_if_false(const bool assertion, const char* msg) {
if(!assertion) {
// endl to flush
std::cout << msg << std::endl;
}
return assertion;
}
int main()
{
int i = 0;
int j = 1;
assert(print_if_false(i == j, "i and j should be equal"));
return 0;
}
断言为Assertion print_if_false(i == j, "i and j should be equal")
。
答案 8 :(得分:0)
如果断言是在类中完成的,另一种方法是调用具有自描述名称的静态谓词函数。如果断言失败,消息将已经包含谓词的漂亮且自描述的名称。
例如:
static bool arguments_must_be_ordered(int a, int b) {return a <= b;}
void foo(int a, int b)
{
assert(arguments_must_be_ordered(a, b));
// ...
}
您甚至可能希望将该谓词函数设为公开,以便类的用户可以自己验证前提条件。
即使没有为发布版本禁用 assert
,如果谓词相当简单,编译器也可能会内联该谓词。
同样的方法可用于需要注释的复杂 if
条件。只需调用自描述谓词函数,而不是注释。
答案 9 :(得分:-5)
对于vc,在assert.h中添加以下代码,
#define assert2(_Expression, _Msg) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Msg), _CRT_WIDE(__FILE__), __LINE__), 0) )