关于c ++:在try catch块中断言


Assert in try catch block

我目前正在向代码段添加处理,以便它不会崩溃。目前,它有每个步骤,然后是一个断言语句,以确保在前一步没有出错。如果这些步骤中有一个出现了问题,就会出现严重的问题。程序应该停止。

虽然在发布模式下,程序命中断言,但很高兴继续运行并崩溃。

为了解决这个问题,我将该方法包装在一个try/catch块中,并在断言原来所在的位置抛出错误。这将捕获我们跟踪的所有错误和我们不跟踪的其他错误。

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

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


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

trycatch是以预期的误差条件(用户供给不存在的文件,呼叫新的库存不允许存储器,使用者输入某些命运的无效输入等)。

是程序员不会犯错的保障。希望当代码在释放中运行的时候你会把代码覆盖在其他的地方并且知道代码是"好的"。典型的assert实例是,用户不应以EDOCX1〕〔7〕作为供货指针,而是不应以NULL作为供货指针,或一份链接列表有预期的节点数[E.G.You count the number of nodes before remove_node,and check that nodes number of nodes is independed ally lesone]。

如果你不是百分之百确定(或至少98.75%确定或你决定的水平是"很好")你已经测试了你所有的代码,那么你就不应该做释放,或者如果你做了,请你的质量保证经理离开"我们没有做足够的测试,但我们同意"。

只有在你的程序中才能真正地恢复不是要抓住"程序员写的愚蠢的代码,这是一个坠机的原因"。

Edit to clarify the actual answer:

另一个词,是的,你应该使用assert因为你不希望在代码中发生〔至少如果程序员不做错事〕-这包括例如检查矢量内在矩阵矢量中的位置是指数的一个广场,如果你希望有一个广场矩阵,比如说,不指针。除了你希望他们在的地方,甚至检查他们是NULL〔7〕时。

当事情发生错误时,实际方案在"现实生活"的运行过程中可能发生错误时——磁盘完整(或只读),文件不存在,没有足够的记忆。


Mats Petersson is right on assert.用它来检查你的内部逻辑。我不会重复这一点。

但我要补充的是,让我们假设你想查看自己的一些东西——为了一个论坛,查看那些本不该出错的东西的结果,但也许是因为系统的其他部分有问题。在这个讲坛上,你应该检查一下(不使用EDOCX1&2),并轻松地处理这个问题。通常要做的事都是throw例外,因为你不(通常)想要这个程序来阻止死亡。另一方面,事情自我改变,以一个例外。你经常想在干净的人身上行走,但如果你想停下,你一定要先清理一下。这就是你要做的


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

一个Assert应该解释"此时,我真诚地相信这个条件失败将是系统处于程序员(我)不期望的状态的标志"。

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

根据断言的严重性,如果事情发展到极端错误,您应该抵制"一瘸一拐"的诱惑。程序的状态应该以可以恢复的方式进行备份,应该通知用户并鼓励用户关闭程序。如果程序可以执行不可逆操作,则强制关闭更为合理。


我想你用的是伺服宏,在释放模式中被排除在外,所以你的代码通过它们快乐地运行。在开发过程中,他们主要用于一种调试,以确保你的程序运行良好。

像他们说的那样思考他们:

this should never happen here, if it happens there's a bug in my code,
so I have to fix it

他们告诉你你犯了错

For example when you check for零divisor:

1
2
3
4
5
6
int x = GetIntFromInput();
if (x != 0);
{
    assert(x != 0);
    float y = 10.0f / x;
}

这个代码有一个永恒的错误,在条件的背后。这一论文将在解构/开发过程中向你提出。

如果你想创建运行时间伺服器的话,就用/抓住它吧,但我真的不喜欢上他们。为什么我不在"尝试"-"摔跤"?也许你可以用ifS或错误代码代替例外情况。


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

答案是日志记录。这将触发一个错误日志,在客户站点或至少对任何进行技术支持的人员都很容易看到该日志。