有没有一种方法来添加或编辑由断言抛出的消息
assert(a == b, "A must be equal to B");
然后,编译器添加 台词、 时间等..。
有可能吗?
我见过的一种黑客行为是使用 &&操作员。因为如果指针是非空的,那么它就是真的,所以您可以在不改变条件的情况下执行以下操作:
&&
assert(a == b && "A is not equal to B");
由于 assert显示了失败的条件,它也将显示您的消息。如果这还不够,您可以编写自己的 myAssert函数或宏来显示您想要的任何内容。
assert
myAssert
断言是宏/函数的组合。您可以使用 __FILE__、 __BASE_FILE__、 __LINE__等定义自己的宏/函数,并使用自己的函数接收自定义消息
__FILE__
__BASE_FILE__
__LINE__
另一种选择是反转操作数并使用逗号运算符。你需要额外的括号,这样逗号就不会被当作参数之间的分隔符:
assert(("A must be equal to B", a == b));
(这是从上面的评论中复制的,以便更好地显示)
BOOST_ASSERT_MSG(expre, msg)
Http://www.boost.org/doc/libs/1_51_0/libs/utility/assert.html
您可以直接使用它,也可以复制 Boost 的代码。还要注意的是,Boost 断言只是头文件,所以如果不想安装所有的 Boost,可以直接抓取这个文件。
对于 vc,在 assert.h 中添加以下代码,
#define assert2(_Expression, _Msg) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Msg), _CRT_WIDE(__FILE__), __LINE__), 0) )
由于 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");
在人类解析方面的代码,即可读性。也不是一个语言黑客。
下面是我的断言宏版本,它接受消息并以清晰的方式打印出所有内容:
#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行
断言失败: MyFunction: 需要非空参数
期望: ptr! = nullptr
来源: C: MyProject src.cpp,第22行
干净漂亮,可以在代码中使用
你也可以编写自己的自定义断言函数,一个非常简单的例子:
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")。
Assertion print_if_false(i == j, "i and j should be equal")
如果断言是在类中完成的,另一种方法是使用自描述名称调用静态谓词函数。如果断言失败,消息将已经包含断言的漂亮和自我描述的名称。
例如:
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条件。不需要注释,只需调用自描述谓词函数即可。
if