C ++中的表达式断言失败消息 [英] Expressive assertion failure messages in C++

查看:264
本文介绍了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆