当可以返回 error/exception 时,从库中终止调用程序(例如,调用 exit())总是错误的吗?
Is it always wrong to terminate the calling program (e.g., call exit()) from a library when an error/exception could be returned instead?
我一直认为答案是明确的:是。
昨天我在comment on reddit.com/r/c_programming中写了以下内容:
Terminating a calling program inside a library is a severe violation of separation of concerns: it's the library's responsibility to return a result, be it the intended result or an error, nothing more, nothing less; whereas it's the caller's responsibility and prerogative to do with that result whatever it deems best.
然而,令我惊讶的是,我在 Stack Overflow 或 Software Engineering 上找不到任何问题可以直接解决这个相当基本的问题。
如果这个问题不是重复的,我想如果它能作为未来这方面的参考点可能会有用——希望看到一些令人信服的论据、官方指南或其他权威来源。
这种问题很难回答,因为没有一种适合所有人。
如果 plugin/library 过早退出程序,可能出现的第一个问题是它会在正常关闭的程序完成任何类型的清理之前停止程序。所以如果一个程序不使用像atexit这样的钩子,on_exit。程序很可能会在不确定的状态下关闭。
All functions registered with atexit(3) and on_exit(3) are called, in
the reverse order of their registration. (It is possible for one of
these functions to use atexit(3) or on_exit(3) to register an
additional function to be executed during exit processing; the new
registration is added to the front of the list of functions that
remain to be called.) If one of these functions does not return
(e.g., it calls _exit(2), or kills itself with a signal), then none
of the remaining functions is called, and further exit processing (in
particular, flushing of stdio(3) streams) is abandoned. If a
function has been registered multiple times using atexit(3) or
on_exit(3), then it is called as many times as it was registered.
http://man7.org/linux/man-pages/man3/exit.3.html
另一个问题是某些程序依赖于某些特定的退出代码,所以如果程序以 exit(0)
退出,它必须退出,因为程序正常结束,否则它应该使用某种退出代码,使对程序的感觉。
如果程序正确实现了退出回调,假设程序可以进行清理,那么直接使用 exit 也不会很糟糕。
另一方面,如果一个程序提供了一些API来退出程序,应该使用它而不是直接退出。
所以这真的取决于程序是否真正处理了 "exiting" 情况。
但是如果我们谈论的是像 NFCReader 库这样的库……或者一些与主程序无关的通用库。如果有一个库会让你的程序在不是不可恢复的错误的情况下死掉,那会很奇怪而且可能很烦人。
在通用库的情况下,库编写者不知道是否有任何使用他们库的程序使用相同的退出代码,或者是否启用了实际退出回调,所以这样做是一个糟糕的主意,并且更糟糕的是,它可能变得更加危险。
想象一下在某些医疗设备上使用的正则表达式库在某些奇怪的情况下无法解析正则表达式并决定在操作过程中退出程序。
我一直认为答案是明确的:是。
昨天我在comment on reddit.com/r/c_programming中写了以下内容:
Terminating a calling program inside a library is a severe violation of separation of concerns: it's the library's responsibility to return a result, be it the intended result or an error, nothing more, nothing less; whereas it's the caller's responsibility and prerogative to do with that result whatever it deems best.
然而,令我惊讶的是,我在 Stack Overflow 或 Software Engineering 上找不到任何问题可以直接解决这个相当基本的问题。
如果这个问题不是重复的,我想如果它能作为未来这方面的参考点可能会有用——希望看到一些令人信服的论据、官方指南或其他权威来源。
这种问题很难回答,因为没有一种适合所有人。
如果 plugin/library 过早退出程序,可能出现的第一个问题是它会在正常关闭的程序完成任何类型的清理之前停止程序。所以如果一个程序不使用像atexit这样的钩子,on_exit。程序很可能会在不确定的状态下关闭。
All functions registered with atexit(3) and on_exit(3) are called, in the reverse order of their registration. (It is possible for one of these functions to use atexit(3) or on_exit(3) to register an additional function to be executed during exit processing; the new registration is added to the front of the list of functions that remain to be called.) If one of these functions does not return (e.g., it calls _exit(2), or kills itself with a signal), then none of the remaining functions is called, and further exit processing (in particular, flushing of stdio(3) streams) is abandoned. If a function has been registered multiple times using atexit(3) or on_exit(3), then it is called as many times as it was registered.
http://man7.org/linux/man-pages/man3/exit.3.html
另一个问题是某些程序依赖于某些特定的退出代码,所以如果程序以 exit(0)
退出,它必须退出,因为程序正常结束,否则它应该使用某种退出代码,使对程序的感觉。
如果程序正确实现了退出回调,假设程序可以进行清理,那么直接使用 exit 也不会很糟糕。
另一方面,如果一个程序提供了一些API来退出程序,应该使用它而不是直接退出。
所以这真的取决于程序是否真正处理了 "exiting" 情况。
但是如果我们谈论的是像 NFCReader 库这样的库……或者一些与主程序无关的通用库。如果有一个库会让你的程序在不是不可恢复的错误的情况下死掉,那会很奇怪而且可能很烦人。
在通用库的情况下,库编写者不知道是否有任何使用他们库的程序使用相同的退出代码,或者是否启用了实际退出回调,所以这样做是一个糟糕的主意,并且更糟糕的是,它可能变得更加危险。
想象一下在某些医疗设备上使用的正则表达式库在某些奇怪的情况下无法解析正则表达式并决定在操作过程中退出程序。