...
The C++ Standard, [support.runtime], paragraph 10 [ISO/IEC 14882-2014], states the following:
The common subset of the C and C++ languages consists of all declarations, definitions, and expressions that may appear in a well formed C++ program and also in a conforming C program. A POF (“plain old function”) is a function that uses only features from this common subset, and that does not directly or indirectly use any function that is not a POF, except that it may use plain lock-free atomic operations. A plain lock-free atomic operation is an invocation of a function f from Clause 29, such that f is not a member function, and either f is the function
atomic_is_lock_free
, or for every atomic argumentA
passed to f,atomic_is_lock_free(A)
yieldstrue
. All signal handlers shall have C linkage. The behavior of any function other than a POF used as a signal handler in a C++ program is implementation-defined.228
Footnote 228 states the following:
In particular, a signal handler using exception handling is very likely to have problems. Also, invoking
std::exit
may cause destruction of objects, including those of the standard library implementation, which, in general, yields undefined behavior in a signal handler.
If your signal handler is not a plain old function, then the behavior of a call to it in response to a signal is implementation-defined, at best, and is likely to result in undefined behavior. All signal handlers must meet the definition of a plain old function. In particular, this definition prohibits addition to the restrictions placed on signal handlers in a C program, this definition also prohibits the use of features that exist in C++ but not in C (such as non-POD [non–plain old data] objects and exceptions), including . This includes indirect use of such features through function calls, and includes the restrictions placed on signal handlers in a C program.
Noncompliant Code Example
...
There is no compliant solution whereby g()
can be called from the signal handler because it allows exceptions. Even if g()
were implemented such that it handled all exceptions and was marked noexcept(true)
, it would still be noncompliant to call it g()
from a signal handler because g()
would still use a feature that is not a part of the common subset of C and C++ features allowed by a signal handler. Therefore, this compliant solution removes the call to g()
from the signal handler , and instead polls a variable of type volatile sig_atomic_t
periodically; if the variable is set to 1
in the signal handler, then g()
is called to respond to the signal.
...