16 Library introduction [library]

16.4 Library-wide requirements [requirements]

16.4.5 Constraints on programs [constraints]

16.4.5.1 Overview [constraints.overview]

Subclause [constraints] describes restrictions on C++ programs that use the facilities of the C++ standard library.
The following subclauses specify constraints on the program's use of namespaces, its use of various reserved names, its use of headers, its use of standard library classes as base classes ([derived.classes]), its definitions of replacement functions, and its installation of handler functions during execution.

16.4.5.2 Namespace use [namespace.constraints]

16.4.5.2.1 Namespace std [namespace.std]

Unless otherwise specified, the behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std.
Unless explicitly prohibited, a program may add a template specialization for any standard library class template to namespace std provided that
  • the added declaration depends on at least one program-defined type, and
  • the specialization meets the standard library requirements for the original template.153
The behavior of a C++ program is undefined if it declares an explicit or partial specialization of any standard library variable template, except where explicitly permitted by the specification of that variable template.
[Note 1: 
The requirements on an explicit or partial specialization are stated by each variable template that grants such permission.
— end note]
The behavior of a C++ program is undefined if it declares
  • an explicit specialization of any member function of a standard library class template, or
  • an explicit specialization of any member function template of a standard library class or class template, or
  • an explicit or partial specialization of any member class template of a standard library class or class template, or
  • a deduction guide for any standard library class template.
A program may explicitly instantiate a class template defined in the standard library only if the declaration
  • depends on the name of at least one program-defined type, and
  • the instantiation meets the standard library requirements for the original template.
Let F denote a standard library function ([global.functions]), a standard library static member function, or an instantiation of a standard library function template.
Unless F is designated an addressable function, the behavior of a C++ program is unspecified (possibly ill-formed) if it explicitly or implicitly attempts to form a pointer to F.
[Note 2: 
Possible means of forming such pointers include application of the unary & operator ([expr.unary.op]), addressof ([specialized.addressof]), or a function-to-pointer standard conversion ([conv.func]).
— end note]
Moreover, the behavior of a C++ program is unspecified (possibly ill-formed) if it attempts to form a reference to F or if it attempts to form a pointer-to-member designating either a standard library non-static member function ([member.functions]) or an instantiation of a standard library member function template.
A translation unit shall not declare namespace std to be an inline namespace ([namespace.def]).
153)153)
Any library code that instantiates other library templates must be prepared to work adequately with any user-supplied specialization that meets the minimum requirements of this document.

16.4.5.2.2 Namespace posix [namespace.posix]

The behavior of a C++ program is undefined if it adds declarations or definitions to namespace posix or to a namespace within namespace posix unless otherwise specified.
The namespace posix is reserved for use by ISO/IEC/IEEE 9945 and other POSIX standards.

16.4.5.2.3 Namespaces for future standardization [namespace.future]

Top-level namespaces whose namespace-name consists of std followed by one or more digits ([lex.name]) are reserved for future standardization.
The behavior of a C++ program is undefined if it adds declarations or definitions to such a namespace.
[Example 1: 
The top-level namespace std2 is reserved for use by future revisions of this International Standard.
— end example]

16.4.5.3 Reserved names [reserved.names]

16.4.5.3.1 General [reserved.names.general]

The C++ standard library reserves the following kinds of names:
If a program declares or defines a name in a context where it is reserved, other than as explicitly allowed by [library], its behavior is undefined.

16.4.5.3.2 Zombie names [zombie.names]

In namespace std, the names shown in Table 38 are reserved for previous standardization:
Table 38: Zombie names in namespace std[tab:zombie.names.std]
auto_ptr
generate_header
pointer_to_binary_function
auto_ptr_ref
get_pointer_safety
pointer_to_unary_function
binary_function
get_temporary_buffer
ptr_fun
binary_negate
get_unexpected
random_shuffle
bind1st
gets
raw_storage_iterator
bind2nd
is_literal_type
result_of
binder1st
is_literal_type_v
result_of_t
binder2nd
istrstream
return_temporary_buffer
codecvt_mode
little_endian
set_unexpected
codecvt_utf16
mem_fun1_ref_t
strstream
codecvt_utf8
mem_fun1_t
strstreambuf
codecvt_utf8_utf16
mem_fun_ref_t
unary_function
const_mem_fun1_ref_t
mem_fun_ref
unary_negate
const_mem_fun1_t
mem_fun_t
uncaught_exception
const_mem_fun_ref_t
mem_fun
undeclare_no_pointers
const_mem_fun_t
not1
undeclare_reachable
consume_header
not2
unexpected_handler
declare_no_pointers
ostrstream
wbuffer_convert
declare_reachable
pointer_safety
wstring_convert
The names shown in Table 39 are reserved as members for previous standardization, and may not be used as a name for object-like macros in portable code:
Table 39: Zombie object-like macros [tab:zombie.names.objmacro]
argument_type
op
second_argument_type
first_argument_type
open_mode
seek_dir
io_state
preferred
strict
The names shown in Table 40 are reserved as member functions for previous standardization, and may not be used as a name for function-like macros in portable code:
Table 40: Zombie function-like macros [tab:zombie.names.fnmacro]
converted
freeze
from_bytes
pcount
stossc
to_bytes
The header names shown in Table 41 are reserved for previous standardization:
Table 41: Zombie headers [tab:zombie.names.header]
<ccomplex>
<codecvt>
<cstdbool>
<ctgmath>
<strstream>
<ciso646>
<cstdalign>

16.4.5.3.3 Macro names [macro.names]

A translation unit that includes a standard library header shall not #define or #undef names declared in any standard library header.
A translation unit shall not #define or #undef names lexically identical to keywords, to the identifiers listed in Table 4, or to the attribute-tokens described in [dcl.attr], except that the names likely and unlikely may be defined as function-like macros ([cpp.replace]).

16.4.5.3.4 External linkage [extern.names]

Each name declared as an object with external linkage in a header is reserved to the implementation to designate that library object with external linkage,154 both in namespace std and in the global namespace.
Each global function signature declared with external linkage in a header is reserved to the implementation to designate that function signature with external linkage.155
Each name from the C standard library declared with external linkage is reserved to the implementation for use as a name with extern "C" linkage, both in namespace std and in the global namespace.
Each function signature from the C standard library declared with external linkage is reserved to the implementation for use as a function signature with both extern "C" and extern "C++" linkage,156 or as a name of namespace scope in the global namespace.
154)154)
The list of such reserved names includes errno, declared or defined in <cerrno>.
155)155)
The list of such reserved function signatures with external linkage includes setjmp(jmp_buf), declared or defined in <csetjmp>, and va_end(va_list), declared or defined in <cstdarg>.
156)156)
The function signatures declared in <cuchar>, <cwchar>, and <cwctype> are always reserved, notwithstanding the restrictions imposed in subclause 4.5.1 of Amendment 1 to the C Standard for these headers.

16.4.5.3.5 Types [extern.types]

For each type T from the C standard library, the types ​::​T and std​::​T are reserved to the implementation and, when defined, ​::​T shall be identical to std​::​T.

16.4.5.3.6 User-defined literal suffixes [usrlit.suffix]

Literal suffix identifiers ([over.literal]) that do not start with an underscore are reserved for future standardization.
Literal suffix identifiers that contain a double underscore __ are reserved for use by C++ implementations.

16.4.5.4 Headers [alt.headers]

If a file with a name equivalent to the derived file name for one of the C++ standard library headers is not provided as part of the implementation, and a file with that name is placed in any of the standard places for a source file to be included, the behavior is undefined.

16.4.5.5 Derived classes [derived.classes]

Virtual member function signatures defined for a base class in the C++ standard library may be overridden in a derived class defined in the program ([class.virtual]).

16.4.5.6 Replacement functions [replacement.functions]

[support] through [exec] and [depr] describe the behavior of numerous functions defined by the C++ standard library.
Under some circumstances, however, certain of these function descriptions also apply to replacement functions defined in the program.
A C++ program may provide the definition for any of the following dynamic memory allocation function signatures declared in header <new> ([basic.stc.dynamic], [new.syn]): operator new(std::size_t) operator new(std::size_t, std::align_val_t) operator new(std::size_t, const std::nothrow_t&) operator new(std::size_t, std::align_val_t, const std::nothrow_t&) operator delete(void*) operator delete(void*, std::size_t) operator delete(void*, std::align_val_t) operator delete(void*, std::size_t, std::align_val_t) operator delete(void*, const std::nothrow_t&) operator delete(void*, std::align_val_t, const std::nothrow_t&) operator new[](std::size_t) operator new[](std::size_t, std::align_val_t) operator new[](std::size_t, const std::nothrow_t&) operator new[](std::size_t, std::align_val_t, const std::nothrow_t&) operator delete[](void*) operator delete[](void*, std::size_t) operator delete[](void*, std::align_val_t) operator delete[](void*, std::size_t, std::align_val_t) operator delete[](void*, const std::nothrow_t&) operator delete[](void*, std::align_val_t, const std::nothrow_t&)
A C++ program may provide the definition of the following function signature declared in header <debugging>: bool std::is_debugger_present() noexcept
The program's definitions are used instead of the default versions supplied by the implementation ([new.delete]).
Such replacement occurs prior to program startup ([basic.def.odr], [basic.start]).
The program's declarations shall not be specified as inline.
No diagnostic is required.

16.4.5.7 Handler functions [handler.functions]

The C++ standard library provides a default version of the following handler function ([support]):
A C++ program may install different handler functions during execution, by supplying a pointer to a function defined in the program or the library as an argument to (respectively): See also subclauses [alloc.errors], Storage allocation errors, and [support.exception], Exception handling.
A C++ program can get a pointer to the current handler function by calling the following functions:
Calling the set_* and get_* functions shall not incur a data race ([intro.races]).
A call to any of the set_* functions shall synchronize with subsequent calls to the same set_* function and to the corresponding get_* function.

16.4.5.8 Other functions [res.on.functions]

In certain cases (replacement functions, handler functions, operations on types used to instantiate standard library template components), the C++ standard library depends on components supplied by a C++ program.
If these components do not meet their requirements, this document places no requirements on the implementation.
In particular, the behavior is undefined in the following cases:
  • For replacement functions ([new.delete]), if the installed replacement function does not implement the semantics of the applicable Required behavior: paragraph.
  • For handler functions ([new.handler], [terminate.handler]), if the installed handler function does not implement the semantics of the applicable Required behavior: paragraph.
  • For types used as template arguments when instantiating a template component, if the operations on the type do not implement the semantics of the applicable Requirements subclause ([allocator.requirements], [container.requirements], [iterator.requirements], [algorithms.requirements], [numeric.requirements]).
    Operations on such types can report a failure by throwing an exception unless otherwise specified.
  • If any replacement function or handler function or destructor operation exits via an exception, unless specifically allowed in the applicable Required behavior: paragraph.
  • If an incomplete type ([basic.types.general]) is used as a template argument when instantiating a template component or evaluating a concept, unless specifically allowed for that component.

16.4.5.9 Function arguments [res.on.arguments]

Each of the following applies to all arguments to functions defined in the C++ standard library, unless explicitly stated otherwise.
  • If an argument to a function has an invalid value (such as a value outside the domain of the function or a pointer invalid for its intended use), the behavior is undefined.
  • If a function argument is described as being an array, the pointer actually passed to the function shall have a value such that all address computations and accesses to objects (that would be valid if the pointer did point to the first element of such an array) are in fact valid.
  • If a function argument is bound to an rvalue reference parameter, the implementation may assume that this parameter is a unique reference to this argument, except that the argument passed to a move assignment operator may be a reference to *this ([lib.types.movedfrom]).
    [Note 1: 
    If the type of a parameter is a forwarding reference ([temp.deduct.call]) that is deduced to an lvalue reference type, then the argument is not bound to an rvalue reference.
    — end note]
    [Note 2: 
    If a program casts an lvalue to an xvalue while passing that lvalue to a library function (e.g., by calling the function with the argument std​::​move(x)), the program is effectively asking that function to treat that lvalue as a temporary object.
    The implementation is free to optimize away aliasing checks which would possibly be needed if the argument was an lvalue.
    — end note]

16.4.5.10 Library object access [res.on.objects]

The behavior of a program is undefined if calls to standard library functions from different threads may introduce a data race.
The conditions under which this may occur are specified in [res.on.data.races].
[Note 1: 
Modifying an object of a standard library type that is shared between threads risks undefined behavior unless objects of that type are explicitly specified as being shareable without data races or the user supplies a locking mechanism.
— end note]
If an object of a standard library type is accessed, and the beginning of the object's lifetime does not happen before the access, or the access does not happen before the end of the object's lifetime, the behavior is undefined unless otherwise specified.
[Note 2: 
This applies even to objects such as mutexes intended for thread synchronization.
— end note]

16.4.5.11 Semantic requirements [res.on.requirements]

A sequence Args of template arguments is said to model a concept C if Args satisfies C ([temp.constr.decl]) and meets all semantic requirements (if any) given in the specification of C.
If the validity or meaning of a program depends on whether a sequence of template arguments models a concept, and the concept is satisfied but not modeled, the program is ill-formed, no diagnostic required.
If the semantic requirements of a declaration's constraints ([structure.requirements]) are not modeled at the point of use, the program is ill-formed, no diagnostic required.