C++中的函数assert()崩溃
Function assert() crash in C++
我刚刚读到一些关于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
因此,这可能是程序的另一个问题,也可能是与开发环境有关的问题。
- 当回溯以零开始时,如何调试崩溃
- 内联映射初始化的动态atexit析构函数崩溃
- 执行函数时导致崩溃的变量
- 程序崩溃并显示"std::out_of_range"错误
- CoInitialize()在单独的线程上崩溃而不返回
- 使用调试/崩溃报告将应用程序部署到客户端
- 为什么所有C++编译器都会崩溃或挂起此代码
- 为什么lambda在clang上崩溃而不是在gcc上崩溃
- 为什么我的多线程作业队列崩溃
- ExtractIconEx:可以工作,但偶尔会崩溃
- 为什么引用传递会导致此崩溃(C++)
- 试图创建流或fopen时程序崩溃
- 类对象数组的问题会导致崩溃
- 排序时无法执行交换操作.我做的时候它会崩溃.为什么
- 为什么要增加导致崩溃的指针
- 在虚幻引擎中删除NXOpen对象时崩溃
- 为什么它只打印双链接列表的第一个值,而我的程序却崩溃了
- 应用程序崩溃并显示"symbol _ZdlPvm, version Qt_5 not defined in file libQt5Core.so.5 with link time reference"
- Visual Studio在尝试读取resource.txt文件时崩溃
- C++中的函数assert()崩溃