I have always believed the answer to be unequivocally: yes.
Yesterday I wrote the following in a 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.
However, to my surprise, I could find no question on Stack Overflow or Software Engineering that directly addresses this fairly fundamental concern.
If this question is not a duplicate, I figure it might be useful if it were to serve as a future point of reference in that regard—hoping to see some convincing arguments, official guidelines, or otherwise authoritative sources.
This kind of question is difficult to answer because there isn't a 1 size fits all.
The first issue that could arise if a plugin/library prematurely exit a program is that it will stop the program before any kind of cleanup can be done by a program closing normally. So if a program doesn't use hooks like atexit, on_exit. It's quite possible that the program will close in an undetermined state.
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
The other problem would be that some program rely on some particular exit codes so if the program exit with exit(0)
it has to exit because the program ended normally otherwise it should use some kind of exit code that make sense to the program.
If the program implement correctly exiting callbacks, it wouldn't be terrible to use exit directly assuming that the program can do the cleanups.
On the other hand, if a program provide some APIs to exit the program it should be used instead of exit directly.
So it really depends if the program actually handle the "exiting" situations.
But if we're talking about a library like an NFCReader library... or something general that isn't coupled with the main program. That would be weird and possibly annoying to have a library that would make your program die in cases that aren't unrecoverable errors.
In the case of a general library, the library writer cannot know if any of the program using their library use the same exit codes, or have actual exitting callbacks enabled so it would be a terrible idea to do that and in worse case it could become even dangerous.
Imagine a regex library being used on some medical equipment that in some weird scenario would fail to parse a regex and decide to exit the program in the middle of an operation.