C++中exit()函数的正确用法?

22

我编写了一个简单的应用程序,它读取数据文件,解析文本并对数据进行一些处理。数据文件在我的main()函数中打开。如果确定文件未正确打开,使用exit()函数是良好的编程实践吗?例如:

if (!file.is_open() ){
     exit(1);
}

此外,我的程序有一个单独的函数来解析文件中的数据。这个函数由 main() 函数调用。如果函数在数据中发现错误,我希望程序在输出错误信息后停止运行。在这种情况下,在我的解析函数中使用 exit() 函数是否可接受?我问这个问题是因为,在我看来,让一个函数自己退出程序而不将控制返回给 main() 函数似乎不太整洁。(如果这个问题显得非常明显,我很抱歉...我对C++和编程一般都比较陌生。)


我不明白这个问题。你的意图是正常终止程序吗?如果是的话,我在这里看不出有什么问题。 - Rapptz
6个回答

20

在函数中调用exit并不是“不好”的意思是它有明确定义的行为 - 这样做并没有根本上的错误。

但是,如果你正在编写一个可能会出现在库中的函数,例如从那里调用exit通常是不好的实践:更好的方法是通过特定的返回值或异常来向调用代码发出错误信号,并让调用代码决定要做什么。(当然也有一些情况下它是完全有效的。例如,如果你正在编写一个名为quit_if_file_not_found的函数,那么你的用户期待终止。)

在你的情况下,你的解析函数可能不应该调用exit:例如,将来你可能希望你的主要代码询问用户是否需要使用不同的文件名,如果解析第一个文件失败了。如果你的解析例程终止程序,你必须修改你的主要代码和那个函数。如果它已经发出了错误条件,你只需要修改main中的逻辑。

(而不要像你上面所做的那样,只是exit而不输出错误消息或记录一些东西,这将使无法知道如何修复代码遇到的任何问题的用户感到沮丧。)


1
我的函数返回类型是void,因此我无法返回任何表示错误的内容。 - mahela007
4
好的,你需要更改那部分代码,使用“输出参数”或者使用异常。既可能失败又没有办法发出错误信号的函数是一种设计错误。 - Mat

7
有两个方面。一个是决定在想要使用 exit 的位置停止程序的兴趣,另一个是使用退出。Mat的答案涵盖了第一点。
对于第二个问题,在C ++中使用 exit 通常是不好的选择。原因是它会进行一些清理工作(使用 atexit 注册的函数,这有时包括一些静态存储期对象的析构函数),但并非全部(堆栈上对象的析构函数)。据我的经验,您要么需要全部清理,要么不需要清理。

3

exit(0) 表示程序成功终止,而且它是完全可移植的,但是

exit(1)(通常)表示不成功的终止。然而,它的使用是不可移植的。


你能提供一个使用不可移植的例子吗? - Rapptz
@Rapptz:这个问题在这个答案的结尾处有讨论。 - johnsyweb
@Johnsyweb 谢谢。我知道 return 0return n(其中 n != 0)之间的区别,但不清楚它如何适用于 std::exit,现在我想我明白了。 - Rapptz
1
@Rapptz: int main() 中的 return n 调用std::exit(n) :-) - johnsyweb

3
main 函数角度来看,exit(1)return 1 没有区别。在使用时,0 表示成功,非 0 表示失败。
如果你的子程序是一个库程序,需要在返回给主函数时附带返回代码或异常信息。否则可以自由选择 exit 或者 return
无论哪种情况,都应该记录函数的功能,无论是 exitreturn 还是 exception

2

这取决于exit(1)来自哪里。你不应该从库中调用这个exit(1),只能从你自己的应用程序中调用。

如果你需要设置错误代码,你可以设置一个errno(STD C变量)。

如果你想尝试更C++的方式,你可以抛出异常,附带详细的错误代码。


1

退出是可以接受的,尽管我认为需要注意使用退出和返回语句时内存差异,因为退出不会销毁内存中的变量。如果出现错误,则可以使用退出。否则,我会坚持使用返回语句。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接