1

单元测试框架通常会提供非常好的断言失败消息(我使用的是 gtest)来描述特定测试的预期值和实际值。此外,您知道函数调用的来源,因为您正在测试类的接口。

相比之下,assert当在实现中用作健全性检查时,会提供一些但更隐秘的信息。例如,我现在正在研究的那个。.

Assertion failed: (latency > std::chrono::milliseconds(0)), function setLatency, file /path/to/my.cpp line 71

所以我知道哪个断言失败了,但我不知道导致它失败的值是什么,更重要的是,我不知道setLatency调用哪个有问题的函数。

一个简单的解决方案通常是放到调试器中,但在这种情况下我不能这样做。是否可以从类的实现中获得更具描述性的断言消息?我怎样才能做到这一点?如有必要,我不介意使用 3rd 方库。

4

2 回答 2

2

这个问题的一个常见解决方案是创建一个断言宏。例如,请参阅此问题。该答案中宏的最终形式如下:

#define dbgassert(EX,...) \
  (void)((EX) || (realdbgassert (#EX, __FILE__, __LINE__, ## __VA_ARGS__),0))

在您的情况下,这realdbgassert将是一个将任何相关信息打印到stderr或其他输出控制台的函数,然后调用 assert 函数本身。根据您需要多少信息,您还可以执行堆栈转储,或记录任何其他有助于您识别问题的相关信息。但是,它可以像传递 printf-esque 格式字符串和相关参数值一样简单。

请注意,如果您的编译器不支持可变参数宏,您可以创建采用特定数量参数的宏。这稍微麻烦一些,但如果您的编译器缺乏支持,则可以选择,例如:

#define dbgassert0(EX) \ ...
#define dbgassert1(EX,p0) \ ...
#define dbgassert2(EX,p0,p1) \ ...
于 2015-06-18T11:50:02.793 回答
0

我不确定这是否是您要查找的内容,但您可以通过执行以下操作将您喜欢的任何消息附加到“断言失败:..”消息中:

assert(1==1 && "This is always true");
assert(1==0 && "This always fails");

当然,您可以修改字符串以包含值或更多信息。

于 2015-06-18T11:49:55.973 回答