C++中的函数assert()崩溃

Function assert() crash in C++

本文关键字:崩溃 assert 函数 C++      更新时间:2023-10-16

我刚刚读到一些关于assert的帖子。在里面,我看到了段落代码:

int a = 5;
assert(a!=5); // crashing

但我不明白它为什么会崩溃:)有人能向我解释吗。非常感谢!

它崩溃了,因为这正是想要做的。您应该将assert行读取为:

断言a不等于5。

换句话说,如果等于5,则断言失败,并引发错误。

例如,根据C11标准(a)7.2.1.1 The assert macro /2(我强调):

assert宏将诊断测试放入程序中;它扩展为一个void表达式。执行时,如果表达式(应具有标量类型)为false(即比较等于0),assert宏以实现定义的格式在标准错误流上写入关于失败的特定调用的信息(包括参数的文本、源文件的名称、源行号和封闭函数的名称——后者分别是预处理宏__FILE____LINE__以及标识符__func__的值)。

然后它调用abort函数

事实上,在大多数情况下,我自己并不喜欢断言,原因如下。

首先,断言往往只对调试代码启用,因为是NDEBUG预处理器宏控制它,而这在调试代码和发布代码之间的设置通常不同。因此,断言往往只有在开发过程中才有用。

其次,即使在发布代码中断言,断言的效果也不是用户应该看到的。与其退出程序,不如优雅地失败。

它们在开发过程中有点有用,但是,开发过程中任何失败的断言都应该是将代码发布到生产中的即时阻断器,直到您对其进行了更体面的错误处理。

这是因为断言要么不会在发布代码中进行测试(结果可能是灾难性的),要么你会在发布代码上进行断言(你的程序会立即中止。这将导致与你的客户进行一些相当坦率的讨论:-)


(a)是的,我知道这是一个C++问题,但C++大多遵循C的传统标头,如cassert。来自C++14 19.3 Assertions /2:

内容与标准C库头<assert.h>相同。

我也知道C++14引用的是C99而不是C11,但断言的内容已经很久没有改变了。

如果您断言的内容不是真的,那么您将崩溃。如果你说a=4或断言(a==5),那么你就没事了。请注意,这只是一个调试函数。

这是对的。

因为如果assert函数中的参数表达式为false,则会向标准错误设备写入一条消息,并调用abort,从而终止程序执行。

在此处输入链接描述

如果这就是您的代码所要做的全部工作,那么它在运行时似乎不会崩溃。我想这也取决于你对"崩溃"的定义。如果你的意思是程序停止运行,那么它就会崩溃——assert()的全部目的是在断言失败时停止运行。如果你的意思是你得到了一个segfault或其他什么,那么它不应该崩溃。我创建了一个简单的程序来尝试复制您的问题:

#include <assert.h>
int main() {
    int a = 5;
    assert(a != 5);
    return 0;
}

我与以下人员一起编制:g++assert.cpp

并运行生成的程序,显示:

断言失败:(a!=5),函数main,文件assert.cpp,第5行。

中止陷阱:6

因此,这可能是程序的另一个问题,也可能是与开发环境有关的问题。