C++17以降のC++標準ライブラリ仕様では、signal
関数のプロトタイプ宣言が読みやすく書き直されている。
C++17仕様
C++標準ライブラリ仕様としてプロトタイプ宣言が行われている。C++17 21.10.3より宣言を引用:
Header <csignal> synopsis
namespace std { // 21.10.4, signal handlers extern "C" using signal-handler = void(int); // exposition only signal-handler* signal(int sig, signal-handler* func); }The contents of the header <csignal> are the same as the C standard library header <signal.h>.
またC++標準において、シグナルハンドラ内で行っても良い Signal-safe 操作の定義がなされている。C++17 21.10.4/p3より引用:
An evaluation is signal-safe unless it includes one of the following:
- a call to any standard library function, except for plain lock-free atomic operations and functions explicitly identified as signal-safe. [Note: This implicitly excludes the use of
new
anddelete
expressions that rely on a library-provided memory allocator. -- end note]- an access to an object with thread storage duration;
- a
dynamic_cast
expression;- throwing of an exception;
- control entering a try-block or function-try-block;
- initialization of a variable with static storage duration requiring dynamic initialization (6.6.3, 9.7); or
- waiting for the completion of the initialization of a variable with static storage duration (9.7).
A signal handler invocation has undefined behavior if it includes an evaluation that is not signal-safe.
C++03/11/14仕様
C++14以前の仕様では独自のプロトタイプ宣言を行わず、標準Cヘッダ<signal.h>を参照している。
シグナルハンドラ内からの(一部例外を除く)C++関数呼び出しは処理系定義(implementation-defined)とされ、Signal-safeに関する言及は存在しない。C++14 18.10/p10より一部引用:
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. (snip) 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
脚注228) In particular, a signal handler using exception handling is very likely to have problems. Also, invokingstd::exit
may cause destruction of objects, including those of the standard library implementation, which, in general, yields undefined behavior in a signal handler (see 1.9).
C仕様
C17 7.14.1.1/p1より宣言を引用:
Synopsis
#include <signal.h> void (*signal(int sig, void (*func)(int)))(int);
シグナルハンドラ内で許可される操作は、条件付きで明示的に列挙されている。C17 7.14.1.1/p4-5より一部引用:
4 If the signal occurs as the result of calling the
abort
orraise
function, the signal handler shall not call theraise
function.
5 If the signal occurs other than as the result of calling theabort
orraise
function, the behavior is undefined if the signal handler refers to any object with static or thread storage duration that is not a lock-free atomic object other than by assigning a value to an object declared asvolatile sig_atomic_t
, or the signal handler calls any function in the standard library other than (snip)
関連URL