VERIFY(...)是C ++编码的好习惯吗?

时间:2010-04-15 02:43:57

标签: c++ coding-style verify

此外,与出现问题时抛出异常相比如何?

3 个答案:

答案 0 :(得分:19)

VERIFY()ASSERT()(或标准库assert())具有相同的目的 - 让您捕捉真正不应该的内容正在发生(即真正的代码错误,应该在发布前修复)。如果由于某种原因表达式是错误的那些事情,没有必要继续下去,因为某些事情是可怕的,可怕的错误。

这反映在VERIFY()仅在调试模式下编译时停止程序进行错误评估的事实 - 在发布模式下,它是透明的。 VERIFY()ASSERT()之间的区别在于VERIFY()仍然会在发布模式下评估表达式,它根本不关心结果 - 而ASSERT()完全从在发布模式下编译时的程序,因此不会发生表达式中的任何副作用。

例外对于可能出错的事情更有用,但可以从中恢复,因为异常可以由程序的其他部分处理。

答案 1 :(得分:6)

问题看起来很简单,但隐藏了一个巨大的主题:处理错误。

Summarilly我会说断言验证开发流程中使用的工具,而例外和系统调用错误检查是生产代码的正常部分,用于处理运行时错误

  • 断言(适用于断言和验证)是主要用于防御性编程风格的工具。他们的主要目标是防止应该永远不会发生的案件,如果发生这种情况,程序员也不知道该怎么做。通常用于检查编程错误。当调试程序时发生不可能的情况时,您通常希望尽快检测并报告它。它将简化纠错。您可以在某些情况下使用它,甚至可以assert(false)使用它来检查交换机的分支是否永远不会被捕获。

    在处理我不确定的行为的第三方代码时,我主要使用断言。为了检查我自己的代码代码在开发中的行为,我通常更喜欢单元测试。

    现在,正如施罗丁格教导我们的那样,情绪改变了一切。当启用断言并停止在释放模式下工作时,您可能有时会在调试模式下运行代码。它通常是断言条件中隐藏的错误的症状(副作用,时间敏感的代码)。验证将这种风险降至最低,但这可能被视为一种不好的做法,例如在地毯后面扫除灰尘。

    您还可以使用验证进行快速编码,作为尚未设置真正错误处理的地方的scafolding。我不相信你应该在生产代码中进行任何验证。

  • 例外是程序控制流程的正常部分。大多数情况下,它们习惯于处理错误,但它不是唯一可能的用法(使用其他语言如python的人会知道我在说什么)。它们也不应被视为唯一的错误管理工具。如果未包含在c ++感知库中,系统调用仍会返回错误代码,而不是引发异常。

    根据经验,异常应该由能够合理处理它们的最近的对象捕获。

    同样不是所有例外都应被视为致命错误并停止计划。想象一下,您正在处理网络视频流库,通过异常返回错误情况。它会抛出一个异常警告,表示帧被删除了,你通常不想停止程序,只是为下一帧做好准备。

    即使最好的办法是停止程序,也不要让异常为你做(并且你甚至没有理由在生产代码中为此目的使用assert)。应始终存在一个顶级异常处理程序,用于显式调用exit()。不这样做只是表明程序员并不关心可能发生的事情,也可能没有考虑过。

答案 2 :(得分:5)

在Visual C ++中,有两个用于检查条件的宏:ASSERTVERIFY

在调试模式下,它们的行为都相同:即,它们都评估它们的argunment,如果结果为0,它们都会使用断言失败对话框暂停程序。

不同之处在于发布模式。在发布模式中,ASSERT完全从程序中删除:它根本不评估它的表达式。另一方面,VERIFY仍然评估表达式,它只是忽略了结果。

个人,我的观点是,如果检查在调试模式下很有价值,那么它在发布模式下仍然很有用,你可能不应该使用它们中的任何一个。只需进行测试并抛出异常(或使用在调试模式下扩展为assert()的自定义宏,在发布模式下使用异常)。