为什么要使用 Q_ASSERT 而不是 assert?

23

在Qt中,有一个Q_ASSERT宏。与从<cassert>中使用的assert相比,使用它有什么优势?

2个回答

36

Q_ASSERT是一种自定义断言宏,据说可以增强标准的assert函数。

错误消息由qFatal()处理,在某些平台上可能比标准的assert宏表现更好。例如在Windows上,它将在断言失败的点触发Visual Studio调试器,而不仅仅是调用abort()

您还可以重定向Qt错误消息函数(如qFatal)的输出到您的自定义消息处理程序(使用qInstallMessageHandler())。例如,如果您想将错误消息重定向到文件中,则这可能很有用。

还请注意,Q_ASSERT使用宏QT_NO_DEBUG禁用(而assertNDEBUG禁用):这可用于将您的断言分开处理,即Qt相关代码和其他代码。


顺便提一下,如果您想要更详细的解释关于自定义断言宏的工作原理以及它们为什么有用,请阅读《游戏编程宝典》中Steve Rabin所著的Squeezing more out of assert - Louen

6

从同一份文件中:

如果在编译期间定义了QT_NO_DEBUG,则不执行任何操作。

所以,请考虑:与assert不同,Q_ASSERT并不取决于是否存在NDEBUG。对于assert()要执行任何操作,需要#ifndef NDEBUG,并且通常用于标记用户(以及可能是库...?)代码中的其他一般调试-only事项。

使用单独的宏对于那些只想调试Qt相关事物而又不想留下未定义的NDEBUG且因此在不定义NDEBUG的情况下使代码加重调试-only内容从而使程序膨胀但不会使用assert()的人来说是有益的。

所以,如果您想将调试应用于Qt内容但仍希望使用发布模式语义来编译“正常”内容,则可以使用-DNDEBUG进行编译,但不能使用-DQT_NO_DEBUG

在开发复杂GUI应用程序时,这肯定非常有用。我目前没有使用Qt,但是看到在我选择的GTK+/gtkmm工具包中使用此类东西的好处[ ……我确定这些存在,但我还没有查找过;-)]

我记得最近在这里有一次关于此事的动画讨论,与一个正交建议的讨论交织在一起:ISO C++ Standard - Future Proposals › Exception stack trace information.


是的,我注意到了不同的调试定义,我想知道是否还有其他更深层次的东西。但是拥有这种可能性是有道理的。 - Zitrax

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接