215 lines
9.3 KiB
Markdown
215 lines
9.3 KiB
Markdown
[support.runtime]
|
||
|
||
# 17 Language support library [[support]](./#support)
|
||
|
||
## 17.14 Other runtime support [support.runtime]
|
||
|
||
### [17.14.1](#general) General [[support.runtime.general]](support.runtime.general)
|
||
|
||
[1](#general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6346)
|
||
|
||
Headers[<csetjmp>](#header:%3ccsetjmp%3e "17.14.3 Header <csetjmp> synopsis [csetjmp.syn]") (nonlocal jumps),[<csignal>](#header:%3ccsignal%3e "17.14.4 Header <csignal> synopsis [csignal.syn]") (signal handling),[<cstdarg>](#header:%3ccstdarg%3e "17.14.2 Header <cstdarg> synopsis [cstdarg.syn]") (variable arguments),
|
||
and[<cstdlib>](cstdlib.syn#header:%3ccstdlib%3e "17.2.2 Header <cstdlib> synopsis [cstdlib.syn]") (runtime environment getenv, system),
|
||
provide further compatibility with C code[.](#general-1.sentence-1)
|
||
|
||
[2](#general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6357)
|
||
|
||
Calls to the functiongetenv ([[cstdlib.syn]](cstdlib.syn "17.2.2 Header <cstdlib> synopsis")) shall not introduce a data
|
||
race ([[res.on.data.races]](res.on.data.races "16.4.6.10 Data race avoidance")) provided that nothing modifies the environment[.](#general-2.sentence-1)
|
||
|
||
[*Note [1](#general-note-1)*:
|
||
|
||
Calls to the POSIX functionssetenv andputenv modify the
|
||
environment[.](#general-2.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[3](#general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6371)
|
||
|
||
A call to the [setlocale](clocale.syn#lib:setlocale "28.3.5.1 Header <clocale> synopsis [clocale.syn]") function
|
||
may introduce a data race with other
|
||
calls to the setlocale function or with calls to functions that are
|
||
affected by the current C locale[.](#general-3.sentence-1)
|
||
|
||
The implementation shall behave as if no
|
||
library function other than locale::global calls the setlocale function[.](#general-3.sentence-2)
|
||
|
||
### [17.14.2](#cstdarg.syn) Header <cstdarg> synopsis [[cstdarg.syn]](cstdarg.syn)
|
||
|
||
[ð](#header:%3ccstdarg%3e)
|
||
|
||
// all freestanding#define __STDC_VERSION_STDARG_H__ 202311Lnamespace std {using [va_list](#lib:va_list "17.14.2 Header <cstdarg> synopsis [cstdarg.syn]") = *see below*;}#define va_arg(V, P) *see below*#define va_copy(VDST, VSRC) *see below*#define va_end(V) *see below*#define va_start(V, ...) *see below*
|
||
|
||
[1](#cstdarg.syn-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6396)
|
||
|
||
The contents of the header <cstdarg> are the same as the C
|
||
standard library header [<stdarg.h>](support.c.headers.general#header:%3cstdarg.h%3e "17.15.1 General [support.c.headers.general]"), with the following changes:
|
||
|
||
- [(1.1)](#cstdarg.syn-1.1)
|
||
|
||
In lieu of the default argument promotions specified in ISO/IEC 9899:2024 6.5.2.2,
|
||
the definition in [[expr.call]](expr.call "7.6.1.3 Function call") applies[.](#cstdarg.syn-1.1.sentence-1)
|
||
|
||
- [(1.2)](#cstdarg.syn-1.2)
|
||
|
||
The preprocessing tokens
|
||
comprising the second and subsequent arguments to va_start (if any)
|
||
are discarded[.](#cstdarg.syn-1.2.sentence-1)
|
||
[*Note [1](#cstdarg.syn-note-1)*:
|
||
va_start accepts a second argument
|
||
for compatibility with prior revisions of C++[.](#cstdarg.syn-1.2.sentence-2)
|
||
â *end note*]
|
||
|
||
See also: ISO/IEC 9899:2024, 7.16
|
||
|
||
### [17.14.3](#csetjmp.syn) Header <csetjmp> synopsis [[csetjmp.syn]](csetjmp.syn)
|
||
|
||
[ð](#lib:jmp_buf)
|
||
|
||
#define __STDC_VERSION_SETJMP_H__ 202311Lnamespace std {using jmp_buf = *see below*; [[noreturn]] void longjmp(jmp_buf env, int val);}#define setjmp(env) *see below*
|
||
|
||
[1](#csetjmp.syn-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6431)
|
||
|
||
The contents of the header <csetjmp> are the same as the C
|
||
standard library header [<setjmp.h>](support.c.headers.general#header:%3csetjmp.h%3e "17.15.1 General [support.c.headers.general]")[.](#csetjmp.syn-1.sentence-1)
|
||
|
||
[2](#csetjmp.syn-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6435)
|
||
|
||
The function signaturelongjmp(jmp_buf jbuf, int val) has more restricted behavior in this document[.](#csetjmp.syn-2.sentence-1)
|
||
|
||
A setjmp/longjmp call pair has undefined
|
||
behavior if replacing the setjmp and longjmp by catch and throw would invoke any non-trivial destructors for any objects
|
||
with automatic storage duration[.](#csetjmp.syn-2.sentence-2)
|
||
|
||
A call to setjmp or longjmp has undefined
|
||
behavior if invoked in a suspension context of a coroutine ([[expr.await]](expr.await "7.6.2.4 Await"))[.](#csetjmp.syn-2.sentence-3)
|
||
|
||
See also: ISO/IEC 9899:2024, 7.13
|
||
|
||
### [17.14.4](#csignal.syn) Header <csignal> synopsis [[csignal.syn]](csignal.syn)
|
||
|
||
[ð](#lib:sig_atomic_t)
|
||
|
||
namespace std {using sig_atomic_t = *see below*; // [[support.signal]](#support.signal "17.14.5 Signal handlers"), signal handlersextern "C" using *signal-handler* = void(int); // *exposition only**signal-handler** signal(int sig, *signal-handler** func); int raise(int sig);}#define SIG_DFL *see below*#define SIG_ERR *see below*#define SIG_IGN *see below*#define SIGABRT *see below*#define SIGFPE *see below*#define SIGILL *see below*#define SIGINT *see below*#define SIGSEGV *see below*#define SIGTERM *see below*
|
||
|
||
[1](#csignal.syn-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6485)
|
||
|
||
The contents of the header <csignal> are the same as the C
|
||
standard library header [<signal.h>](support.c.headers.general#header:%3csignal.h%3e "17.15.1 General [support.c.headers.general]")[.](#csignal.syn-1.sentence-1)
|
||
|
||
### [17.14.5](#support.signal) Signal handlers [[support.signal]](support.signal)
|
||
|
||
[1](#support.signal-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6491)
|
||
|
||
A call to the function signal synchronizes with any resulting
|
||
invocation of the signal handler so installed[.](#support.signal-1.sentence-1)
|
||
|
||
[2](#support.signal-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6495)
|
||
|
||
A [*plain lock-free atomic operation*](#def:plain_lock-free_atomic_operation "17.14.5 Signal handlers [support.signal]") is
|
||
an invocation of a function f from [[atomics]](atomics "32.5 Atomic operations"),
|
||
such that:
|
||
|
||
- [(2.1)](#support.signal-2.1)
|
||
|
||
f is the function atomic_is_lock_free(), or
|
||
|
||
- [(2.2)](#support.signal-2.2)
|
||
|
||
f is the member function is_lock_free(), or
|
||
|
||
- [(2.3)](#support.signal-2.3)
|
||
|
||
f is a non-static member function of class atomic_flag, or
|
||
|
||
- [(2.4)](#support.signal-2.4)
|
||
|
||
f is a non-member function, and
|
||
the first parameter of f has type cv atomic_flag*, or
|
||
|
||
- [(2.5)](#support.signal-2.5)
|
||
|
||
f is a non-static member function invoked on an object A,
|
||
such that A.is_lock_free() yields true, or
|
||
|
||
- [(2.6)](#support.signal-2.6)
|
||
|
||
f is a non-member function, and
|
||
for every pointer-to-atomic argument A passed to f,atomic_is_lock_free(A) yields true[.](#support.signal-2.sentence-1)
|
||
|
||
[3](#support.signal-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6523)
|
||
|
||
An evaluation is [*signal-safe*](#def:evaluation,signal-safe "17.14.5 Signal handlers [support.signal]") unless it includes one of the following:
|
||
|
||
- [(3.1)](#support.signal-3.1)
|
||
|
||
a call to any standard library function,
|
||
except for plain lock-free atomic operations and
|
||
functions explicitly identified as signal-safe;
|
||
[*Note [1](#support.signal-note-1)*:
|
||
This implicitly excludes the use of new and delete expressions
|
||
that rely on a library-provided memory allocator[.](#support.signal-3.1.sentence-1)
|
||
â *end note*]
|
||
|
||
- [(3.2)](#support.signal-3.2)
|
||
|
||
an access to an object with thread storage duration;
|
||
|
||
- [(3.3)](#support.signal-3.3)
|
||
|
||
a dynamic_cast expression;
|
||
|
||
- [(3.4)](#support.signal-3.4)
|
||
|
||
throwing of an exception;
|
||
|
||
- [(3.5)](#support.signal-3.5)
|
||
|
||
control entering a [*try-block*](except.pre#nt:try-block "14.1 Preamble [except.pre]") or [*function-try-block*](except.pre#nt:function-try-block "14.1 Preamble [except.pre]");
|
||
|
||
- [(3.6)](#support.signal-3.6)
|
||
|
||
initialization of a variable with static storage duration
|
||
requiring dynamic initialization ([[basic.start.dynamic]](basic.start.dynamic "6.10.3.3 Dynamic initialization of non-block variables"), [[stmt.dcl]](stmt.dcl "8.10 Declaration statement"))[191](#footnote-191 "Such initialization can occur because it is the first odr-use ([term.odr.use]) of that variable.") ; or
|
||
|
||
- [(3.7)](#support.signal-3.7)
|
||
|
||
waiting for the completion of the initialization of a variable with static storage duration ([[stmt.dcl]](stmt.dcl "8.10 Declaration statement"))[.](#support.signal-3.sentence-1)
|
||
|
||
A signal handler invocation has undefined behavior if it includes
|
||
an evaluation that is not signal-safe[.](#support.signal-3.sentence-2)
|
||
|
||
[4](#support.signal-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6563)
|
||
|
||
The function signal is signal-safe if it is invoked
|
||
with the first argument equal to the signal number
|
||
corresponding to the signal that caused the invocation of the handler[.](#support.signal-4.sentence-1)
|
||
|
||
See also: ISO/IEC 9899:2024, 7.14
|
||
|
||
[191)](#footnote-191)[191)](#footnoteref-191)
|
||
|
||
Such initialization can occur because it is the first odr-use ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3 One-definition rule")) of that variable[.](#footnote-191.sentence-1)
|