C ++中的表达式断言失败消息 [英] Expressive assertion failure messages in C++
问题描述
单元测试框架通常提供非常好的断言失败消息(我使用gtest)描述特定测试的预期值和实际值。此外,你知道函数调用的起源,因为你正在测试类的接口。
Unit test frameworks generally provide very nice assertion failure messages (I'm using gtest) describing expected and actual values to a particular test. Furthermore, you know the origin of the function call because you're testing the interface of the class.
相反, assert
,当用作一个健康检查的实现提供了一些,但是更加隐秘的信息。例如,我现在工作的那个。 。
In contrast, assert
, when used as a sanity check in the implementation provides some, but more cryptic information. For example, the one I'm working on now . .
Assertion failed: (latency > std::chrono::milliseconds(0)), function setLatency, file /path/to/my.cpp line 71
所以我知道哪个断言失败,但我不知道值是导致它失败,更重要的是,我不知道从 setLatency
调用的有问题的函数。
So I know which assertion failed, but I have no idea what the values were that caused it to fail, and more importantly, I don't know the problematic function from which setLatency
was called.
一个简单的解决方案通常会被丢弃到调试器,但是我不能在这个实例中做这个。是否可能从类的实现中获取更具描述性的断言消息?我如何做到这一点?如果需要,我不介意使用第三方库。
A simple solution normally would be drop to the debugger, but I cannot do this in this instance. Is it possible to get a more descriptive assertion message from within the implementation of a class? How can I do this? I don't mind using a 3rd party lib if necessary.
推荐答案
这个问题的常见解决方案是创建一个assert宏。有关示例,请参见此问题。在它的宏的最后形式是以下:
A common solution for this problem is to create an assert macro. For an example see this question. The final form of their macro in that answer was the following:
#define dbgassert(EX,...) \
(void)((EX) || (realdbgassert (#EX, __FILE__, __LINE__, ## __VA_ARGS__),0))
在你的情况下, realdbgassert
是一个将任何相关信息打印到 stderr
或其他输出控制台,然后调用assert函数本身。根据所需的信息量,您还可以执行堆栈转储,或记录任何其他有助于您确定问题的相关信息。但是,它可以像传递printf-esque格式字符串和相关参数值一样简单。
In your case, the realdbgassert
would be a function that prints any relevant information to stderr
or other output console, and then calls the assert function itself. Depending on how much information you want, you could also do a stack dump, or log any other relevant information that will help you identify the issue. However, it can be as simple as passing a printf-esque format string, and relevant parameter value(s).
请注意,如果编译器不支持可变宏,您可以创建包含特定数量的参数的宏。这是稍微麻烦一点,但是如果你的编译器缺乏支持,一个选项,例如:
Note that if you compiler doesn't support variadic macros, you can create macros that take a specific number of parameters instead. This is slightly more cumbersome, but an option if your compiler lacks the support, eg:
#define dbgassert0(EX) \ ...
#define dbgassert1(EX,p0) \ ...
#define dbgassert2(EX,p0,p1) \ ...
这篇关于C ++中的表达式断言失败消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!