在try catch块中断言

时间:2015-03-10 20:54:24

标签: c++

我目前正在为一段代码添加处理,以便它不会崩溃。目前,每个步骤都有一个ASSERT语句,以确保在上一步中没有出错。如果在其中一个步骤中出现问题,则确实出现了问题。该计划应该停止。

虽然在发布模式下程序会命中一个断言,然后快乐地继续前进并崩溃。

为了解决这个问题,我已将该方法包装在try / catch块中,并在以前的断言处抛出错误。这应该记录我们跟踪的所有错误以及其他我们没有记录的错误。

现在我的问题是,我是否还应该使用断言通知程序员这不应该发生?或者现在它们会因为catch块(我清理对象)而不会崩溃?

或者我应该只在catch块中抛出一个断言而不是每个throw语句?

5 个答案:

答案 0 :(得分:14)

try& catchassert的目的完全不同(至少在我看来)。

trycatch用于处理预期的错误情况(用户提供的文件名不存在,调用新的不能分配内存,用户输入的无效输入某种等等。)

assert的目的是保证程序员不会犯错误。希望在发布时运行代码时,您已经涵盖了这些替代方案,并且知道代码是好的"。 assert的典型示例是用户不应提供的指针,因为NULL确实不是NULL,或者链表具有预期的节点数[例如}你计算remove_node之前的节点数,并检查节点的数量确实少了一个]。

如果您不是100%确定(或者至少98.75%确定或您决定的任何级别"足够好")您已经测试了所有代码,那么您不应该发布 - 或者,如果你这样做,请让你的质量保证经理签署"我们还没有做足够的测试,但我们对此很好。"。

trycatch只应用于您的程序可以可靠地恢复的内容。不要抓住"程序员写了导致崩溃的愚蠢代码"。

编辑以澄清实际答案:

换句话说,是的,您应该使用assert来表示您不希望在代码中发生的事情[至少如果程序员没有做错事] - 这包括例如例如,当你期望有一个方形矩阵或者指针不是NULL时,检查矩阵向量内的向量确实是一个正方形[除了你期望它们的位置 - 甚至可能检查一下他们应该是NULL

当出现问题时,您应该使用try / catchthrow进行错误检查,这可能会在实际程序运行期间发生,现实生活中&#34 34; - 磁盘已满(或只读),文件不存在,内存不足,等等。

答案 1 :(得分:3)

Mats Petersson在assert上非常正确。它的使用是预发布,以检查您的内部逻辑。我不会重复这一点。

但是,我要添加的是,我们假设您要检查其他内容 - 例如,检查应该永远不会出错的内容的结果,但可能会例如,由于系统其他部分的问题。在这种情况下,您应该检查它(不使用assert),并优雅地处理这种情况。通常情况下,throw是一个例外,因为你没有(通常)希望程序在没有错误的情况下停止运行。或者事物本身抛出异常。通常你想要以干净的方式继续,但如果你想要停止,你几乎肯定想先做一定程度的清理。那就是你的catch阻止等意图。

答案 2 :(得分:2)

我认为您使用断言宏,在发布模式时排除了,这就是您的代码通过它们快乐运行的原因。它们主要用于一种调试,在开发过程中确保您的程序运行良好。

想想他们就像他们说的那样:

  

这应该永远不会发生在这里,如果它发生在我的代码中有一个错误,   所以我必须解决它

他们告诉你,你犯了(逻辑)错误。

例如,当您检查零除数时:

int x = GetIntFromInput();
if (x != 0);
{
    assert(x != 0);
    float y = 10.0f / x;
}

此代码有一个语义错误,条件后面的;。这个断言会在调试/开发构建过程中警告你。

如果你想创建'run-time'断言,只需使用try / catch块,但是我真的不喜欢抛出它们。 Why should I not wrap every block in "try"-"catch"?。也许您可以使用if - s或错误代码替换例外。

答案 3 :(得分:2)

防御性编程包括在每行代码中定义您的假设,仍然检查它们

Assert应该解释“此时,我真的相信这种情况失败将表明系统处于程序员(我)不期望的状态”。

让代码检查假设的失败,并提前退出,是防御性编程的一个例子。但是这些失败只应发生在特殊的单元测试中,这些测试打破了各种接口的前提条件(禁用断言)。如果它发生在正常的单元测试中,或者在正常使用中,或者在用户系统上,那么您需要在其他地方移动保护以防止故障,或者使故障成为预期的故障模式。

根据断言的严重程度,如果情况出现极端错误,你应该抵制“跛行”的诱惑。应该以可以恢复的方式备份程序的状态,应该通知用户并鼓励用户关闭程序。如果您的程序可以执行不可逆转的操作,则强制关闭更合理。

答案 4 :(得分:1)

我刚刚意识到问题没有得到回答。我将解决这个问题,而不是关于断言和异常应该和不应该做什么的另一个讲座:"现在我的问题是,我是否应该使用断言通知程序员这不应该发生?& #34;

答案是记录。这应该会触发一个错误日志,这个日志很容易在客户站点上显示,或者至少对您的任何人提供技术支持。