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

sev*_*axx 10 c++ coding-style verify

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

Amb*_*ber 20

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

这反映在以下事实中:VERIFY()在调试模式下编译时仅在错误评估时停止程序 - 在发布模式下,它是透明的.之间的区别VERIFY()和ASSERT()是VERIFY()仍然会评估在Release模式的表达,它根本不会在乎结果-而ASSERT()在Release模式下进行编译,从而当表达的任何副作用内事情不会完全从计划中删除发生.

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


kri*_*iss 7

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

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

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

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

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

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

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

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

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

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

  • 为'未捕获的异常'设置顶级异常处理程序的缺点是,当发生未捕获的异常时,堆栈会被销毁到顶级处理程序; 然后会做一些完全无趣的事情,比如说发生了哪个例外,然后如你所说,无论如何退出程序.完全不处理它使调试器有机会在std :: terminate处停止程序,整个执行堆栈可用且可检查. (3认同)

Dea*_*ing 5

在Visual C++中,有两个用于检查条件的宏:ASSERT和VERIFY.

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

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

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