Should set_terminate
/get_terminate
set a different terminate exception processor for several threads in C++ 2011 or C++ 2003?
E.g. if I have pr
C2003 has no threads, any thread support is a vendor extension so only vendor-supplied documentation has the answer. If the handler is per thread, the documentation ought to say that. No implementation I know does it.
C++2011 says nothing about per-thread nature of the terminate handler. It would make little sense to maintain it per thread, because you cannot kill a thread in C++11. And for a good reason too (google kill+thread+c++11). So whatever you do, the program must terminate. It looks like having different ways to terminate the program depending on the thread that requested it is not a feature anyone needs.
17.6.4.7p4 says:
Calling the
set_*
andget_*
functions shall not incur a data race. A call to any of theset_*
functions shall synchronize with subsequent calls to the sameset_*
function and to the correspondingget_*
function.
This strongly implies that the set_*
and get_*
functions are operating on the same global state even when called from different threads. All the paragraphs under 18.8.3 discuss "the current handler function", with no other mention of threading; this indicates that the handler function is a property of the program as a whole; similarly, 17.6.4.7 has:
2 - A C++ program may install different handler functions during execution [...]
3 - A C++ program can get a pointer to the current handler function by calling the following functions [...]
These paragraphs discuss the current handler function in the context of a program, indicating that it is program-scope and not thread-local.
In the Standard it says under
18.8.3.2 set_terminate [set.terminate]
terminate_handler set_terminate(terminate_handler f) noexcept;
1 Effects: Establishes the function designated by f as the current handler function for terminating exception processing.
[[noreturn]] void terminate() noexcept;
2 Effects: Calls the current terminate_handler function. [ Note: A default terminate_handler is always considered a callable handler in this context. —end note ]
You can see that terminate()
calls the current terminate handler, which in the set_handler
section it quite clearly says it is used for terminating a process. This gets called when all other exception handling has failed, irrespective from which thread is running.
There is only one terminate handler, and it always gets called from wherever the program is terminating.
The standard doesn't exactly specify; [set.terminate] states only
[...] the current handler function for terminating exception processing.
but doesn't mention if "current" is global or per-thread. So it depends on the implementation.
For example, in MSVC++: https://msdn.microsoft.com/en-us/library/t6fk7h29.aspx
In a multithreaded environment, terminate functions are maintained separately for each thread. Each new thread needs to install its own terminate function. Thus, each thread is in charge of its own termination handling.