问题描述
我有练习使用c ++ assert来检查程序是否正常运行,例如:
cv::Mat im = imread("pic.jpg")
assert(!im);
这将检查图像是否正确读取。这很有用,因为图像可能未正确放置在预期目录中,因此我们需要检查。我觉得使用assert
很方便,但是人们说使用assert
会给程序带来开销,并且建议不要使用它们。为什么assert
会带来开销?在这种情况下进行检查的最佳做法是什么?
解决方法
首先,assert()
不是普通函数。看起来与此类似的是宏:
#ifdef NDEBUG
#define assert(condition) ((void)0)
#else
#define assert(condition) /*implementation*/
#endif
,如您所见,它仅在未定义NDEBUG
的情况下才启用并执行某些操作。它旨在在您以 debug模式运行时对程序进行额外检查,以帮助查明错误(例如错误的参数,不成立的不变量等) )。
如果您按照显示的方式使用它,Assert本身可能不会花费那么多的性能,但是由于我上面写的内容(它是调试工具),可能会在许多代码库中使用。如果传递给断言的条件很复杂,请确保可能需要花费一些时间来评估它们(您的客户不必担心,因为这只会在调试模式下发生,因此它们不会受到影响-NDEBUG
的所有开销将会消失)。
您不应该使用assert()
来验证要始终验证的内容(也在非调试模式下)。在这种情况下,这样做是正确的:
cv::Mat im = imread("pic.jpg")
if (!im) {
/* handle error ... */
}
,
为什么c ++ assert()函数会带来程序开销
首先,assert
在技术上不是函数。这是一个宏。
要回答这个问题:这取决于。如果断言被禁用,那么将不会进行检查,因此不会产生开销。如果启用了断言,则是,与没有检查相比,将会有开销(除非编译器可以在编译时证明不需要检查)。
,任何其他代码都会在程序中添加“开销”,例如增加执行时间,代码大小,甚至可能是RAM大小。
对于使用assert()
的代码也是如此(除了以下细节:assert()
仅执行其工作,并且仅在活动时使用任何资源,即如果未使用-DNDEBUG
;则归功于DevSolar详细信息)。
尽管如此,带或不带assert()
的两种代码都被添加到程序中,因为它们当然是有目的的。
您已经清楚,充分地描述了使用assert()
的目的。
现在的问题不是它是否使用任何资源,而是您是否想实现目的,您可能愿意为此付出使用资源的代价。
由于您似乎很清楚这些好处,因此使用assert()
似乎是一个适当的决定。
如果您要使用assert()
的任何替代方法,答案是没有任何资源可以支持同一目的,而无需使用任何资源。
您可能还需要考虑在不再需要自检功能的情况下(我认为通常不再需要)并且真正专注于“无开销”的情况,那么您可以使用上述开关来删除资源消费。