有问题关于使用exit
C++中.答案讨论主要是因为RAII不是好主意,例如,如果exit
在代码中某处调用,则不会调用对象的析构函数,因此,如果例如析构函数是为了将数据写入文件,则不会发生这种情况,因为没有调用析构函数.
我感兴趣的是C中的这种情况.类似的问题是否也适用于C?我想在C中我们不使用构造函数/析构函数,C中的情况可能会有所不同.所以exit
在C中使用是否可以?
我已经看到了下面的函数,我觉得在某些情况下可以使用它,但是如果我们在C中使用类似的问题感兴趣exit
,如上面用C++所述?(这将使使用下面的功能不是一个好主意.).
void die(const char *message)
{
if(errno) {
perror(message);
} else {
printf("ERROR: %s\n", message);
}
exit(1);
}
Run Code Online (Sandbox Code Playgroud)
Grz*_*ski 81
而不是abort()
,exit()
C中的函数被认为是"优雅"的退出.
从C11(N1570)7.22.4.4/p2 退出功能(强调我的):
该
exit
功能导致正常程序终止.
该标准还在7.22.4.4/p4中说:
接下来,刷新所有带有未写入缓冲数据的打开流,关闭所有打开的流,并
tmpfile
删除该功能创建的所有文件.
它还值得一看7.21.3/p5 文件:
如果
main
函数返回其原始调用者,或者调用该exit
函数,则在程序终止之前关闭所有打开的文件(因此刷新所有输出流).程序终止的其他路径(例如调用abort
函数)无需正确关闭所有文件.
但是,如下面的评论中所述,您不能假设它将涵盖所有其他资源,因此您可能需要atexit()
单独使用并定义其发布的回调.实际上它正是atexit()
打算做的,正如7.22.4.2/p2中所说的atexit函数:
该
atexit
函数注册指向的函数func
,在正常程序终止时无参数调用.
值得注意的是,C标准并未准确说明分配存储持续时间(即malloc()
)对象应该发生什么,因此需要您了解如何在特定实现上完成.对于面向主机的现代操作系统,系统很可能会处理它,但您仍然可能需要自己处理这个问题,以便使内存调试器(如Valgrind)静音.
t0m*_*13b 22
是的,可以exit
在C中使用.
为确保所有缓冲区和正常有序关闭,建议使用此功能atexit
,此处有更多相关信息
示例代码如下:
void cleanup(void){
/* example of closing file pointer and free up memory */
if (fp) fclose(fp);
if (ptr) free(ptr);
}
int main(int argc, char **argv){
/* ... */
atexit(cleanup);
/* ... */
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在,每当exit
调用时,该函数cleanup
将被执行,这可以容纳正常关闭,清理缓冲区,内存等.
enr*_*cis 14
您没有构造函数和析构函数,但您可以拥有资源(例如文件,流,套接字),并且正确关闭它们非常重要.无法同步写入缓冲区,因此退出程序而不首先正确关闭资源可能会导致损坏.
Jon*_*ler 10
exit()
还可以尚未提及的代码设计的两个主要方面是"线程"和"库".
在单线程程序中,在您编写的代码中实现该程序,使用exit()
很好.当程序出错并且代码无法恢复时,我的程序会定期使用它.
但是,召唤exit()
是一种无法撤消的单方面行动.这就是'线程'和'图书馆'需要仔细考虑的原因.
如果一个程序是多线程的,那么使用exit()
是一个戏剧性的动作,它会终止所有的线程.退出整个程序可能不合适.退出线程,报告错误可能是适当的.如果您认识到该计划的设计,那么也许允许单方面退出,但总的来说,这是不可接受的.
并且"认识到程序设计"条款也适用于库中的代码.通用库函数调用很少是正确的exit()
.如果其中一个标准C库函数由于错误而无法返回,那么你有理由感到不安.(很明显,功能等exit()
,_Exit()
,quick_exit()
,abort()
意图不返回;这是不同的.)在C库中的功能因此不是"不能失败"或以某种方式返回一个错误指示.如果您正在编写代码以进入通用库,则需要仔细考虑代码的错误处理策略.它应该适合与其一起使用的程序的错误处理策略,或者可以使错误处理可配置.
我有一系列的库函数(在带有标题的包中"stderr.h"
,一个踩在薄冰上的名称),它们在用于错误报告时会退出.这些功能按设计退出.在同一个包中有一系列相关的函数报告错误而不退出.当然,现有功能是根据非退出功能实现的,但这是一个内部实现细节.
我有许多其他库函数,其中很多都依赖于"stderr.h"
错误报告代码.这是我做出的一个设计决定,也是我很满意的.但是当使用退出的函数报告错误时,它会限制库代码的一般用途.如果代码调用了不退出的错误报告函数,那么函数中的主代码路径必须明智地处理错误返回 - 检测它们并将错误指示转发给调用代码.
我的错误报告包中的代码是在我使用SOQ(堆栈溢出问题)库在GitHub上的文件stderr.c
,并stderr.h
在SRC/libsoq子目录.
避免exit
使用其他函数的一个原因main()
是您的代码可能会脱离上下文.请记住,exit是一种非本地控制流.像无法捕捉的例外.
例如,您可能会编写一些在关键磁盘错误时退出的存储管理功能.然后有人决定将它们移到图书馆.退出库会导致调用程序以不一致的状态退出,而这可能是不准备的.
或者您可以在嵌入式系统上运行它.没有地方可以退出来,整个事情在运行while(1)
中循环main()
.它甚至可能不在标准库中定义.
归档时间: |
|
查看次数: |
10478 次 |
最近记录: |