17 Library introduction [library]

17.6 Library-wide requirements [requirements]

17.6.4 Constraints on programs [constraints]

17.6.4.1 Overview [constraints.overview]

This section 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 ([namespace.std]), its use of various reserved names ([reserved.names]), its use of headers ([alt.headers]), its use of standard library classes as base classes ([derived.classes]), its definitions of replacement functions ([replacement.functions]), and its installation of handler functions during execution ([handler.functions]).

17.6.4.2 Namespace use [namespace.constraints]

17.6.4.2.1 Namespace std [namespace.std]

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 otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.182

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.

A program may explicitly instantiate a template defined in the standard library only if the declaration depends on the name of a user-defined type and the instantiation meets the standard library requirements for the original template.

A translation unit shall not declare namespace std to be an inline namespace ([namespace.def]).

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 the Standard.

17.6.4.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 9945 and other POSIX standards.

17.6.4.3 Reserved names [reserved.names]

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 this Clause, its behavior is undefined.

17.6.4.3.1 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 [tab:identifiers.special], or to the attribute-tokens described in [dcl.attr].

17.6.4.3.2 Global names [global.names]

Certain sets of names and function signatures are always reserved to the implementation:

  • Each name that contains a double underscore __ or begins with an underscore followed by an uppercase letter ([lex.key]) is reserved to the implementation for any use.

  • Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.

17.6.4.3.3 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,183 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. 184

Each name from the Standard C 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 Standard C library declared with external linkage is reserved to the implementation for use as a function signature with both extern "C" and extern "C++" linkage, 185 or as a name of namespace scope in the global namespace.

The list of such reserved names includes errno, declared or defined in <cerrno>.

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>.

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.

17.6.4.3.4 Types [extern.types]

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

These types are clock_t, div_t, FILE, fpos_t, lconv, ldiv_t, mbstate_t, ptrdiff_t, sig_atomic_t, size_t, time_t, tm, va_list, wctrans_t, wctype_t, and wint_t.

17.6.4.3.5 User-defined literal suffixes [usrlit.suffix]

Literal suffix identifiers that do not start with an underscore are reserved for future standardization.

17.6.4.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 ([cpp.include]), the behavior is undefined.

17.6.4.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]).

17.6.4.6 Replacement functions [replacement.functions]

Clauses [language.support] through [thread] and Annex [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 ([definitions]).

A C++ program may provide the definition for any of eight dynamic memory allocation function signatures declared in header <new> ([basic.stc.dynamic], [support.dynamic]):

  • operator new(std::size_t)

  • operator new(std::size_t, const std::nothrow_t&)

  • operator new[](std::size_t)

  • operator new[](std::size_t, const std::nothrow_t&)

  • operator delete(void*)

  • operator delete(void*, const std::nothrow_t&)

  • operator delete[](void*)

  • operator delete[](void*, const std::nothrow_t&)

The program's definitions are used instead of the default versions supplied by the implementation ([support.dynamic]). Such replacement occurs prior to program startup ([basic.def.odr], [basic.start]). The program's definitions shall not be specified as inline. No diagnostic is required.

17.6.4.7 Handler functions [handler.functions]

The C++ standard library provides default versions of the following handler functions (Clause [language.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):

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. A call to any of the set_* functions shall synchronize with subsequent calls to the same set_* function and to the corresponding get_* function.

17.6.4.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, the Standard places no requirements on the implementation.

In particular, the effects are 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], [unexpected.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], [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]) is used as a template argument when instantiating a template component, unless specifically allowed for that component.

17.6.4.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 binds to an rvalue reference parameter, the implementation may assume that this parameter is a unique reference to this argument. [ Note: If the parameter is a generic parameter of the form T&& and an lvalue of type A is bound, the argument binds to an lvalue reference ([temp.deduct.call]) and thus is not covered by the previous sentence.  — end note ] [ Note: 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 move(x)), the program is effectively asking that function to treat that lvalue as a temporary. The implementation is free to optimize away aliasing checks which might be needed if the argument was an lvalue.  — end note ]

17.6.4.10 Shared objects and the library [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: 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 sharable without data races or the user supplies a locking mechanism.  — end note ]

Note: In particular, the program is required to ensure that completion of the constructor of any object of a class type defined in the standard library happens before any other member function invocation on that object and, unless otherwise specified, to ensure that completion of any member function invocation other than destruction on such an object happens before destruction of that object. This applies even to objects such as mutexes intended for thread synchronization.  — end note ]

17.6.4.11 Requires paragraph [res.on.required]

Violation of the preconditions specified in a function's Requires: paragraph results in undefined behavior unless the function's Throws: paragraph specifies throwing an exception when the precondition is violated.