Стандарт C++ 11 (1119564), страница 22
Текст из файла (страница 22)
Destructorsfor initialized objects with thread storage duration within a given thread are called as a result of returningfrom the initial function of that thread and as a result of that thread calling std::exit. The completionsof the destructors for all initialized objects with thread storage duration within that thread are sequencedbefore the initiation of the destructors of any object with static storage duration. If the completion of the34) A non-local variable with static storage duration having initialization with side-effects must be initialized even if it is notodr-used (3.2, 3.7.1).§ 3.6.364© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)constructor or dynamic initialization of an object with thread storage duration is sequenced before that ofanother, the completion of the destructor of the second is sequenced before the initiation of the destructorof the first.
If the completion of the constructor or dynamic initialization of an object with static storageduration is sequenced before that of another, the completion of the destructor of the second is sequencedbefore the initiation of the destructor of the first. [ Note: This definition permits concurrent destruction.— end note ] If an object is initialized statically, the object is destroyed in the same order as if the object wasdynamically initialized.
For an object of array or class type, all subobjects of that object are destroyed beforeany block-scope object with static storage duration initialized during the construction of the subobjects isdestroyed. If the destruction of an object with static or thread storage duration exits via an exception,std::terminate is called (15.5.1).2If a function contains a block-scope object of static or thread storage duration that has been destroyed andthe function is called during the destruction of an object with static or thread storage duration, the programhas undefined behavior if the flow of control passes through the definition of the previously destroyed blockscope object.
Likewise, the behavior is undefined if the block-scope object is used indirectly (i.e., through apointer) after its destruction.3If the completion of the initialization of an object with static storage duration is sequenced before a callto std::atexit (see <cstdlib>, 18.5), the call to the function passed to std::atexit is sequenced beforethe call to the destructor for the object. If a call to std::atexit is sequenced before the completion of theinitialization of an object with static storage duration, the call to the destructor for the object is sequencedbefore the call to the function passed to std::atexit.
If a call to std::atexit is sequenced before anothercall to std::atexit, the call to the function passed to the second std::atexit call is sequenced before thecall to the function passed to the first std::atexit call.4If there is a use of a standard library object or function not permitted within signal handlers (18.10) thatdoes not happen before (1.10) completion of destruction of objects with static storage duration and executionof std::atexit registered functions (18.5), the program has undefined behavior. [ Note: If there is a useof an object with static storage duration that does not happen before the object’s destruction, the programhas undefined behavior.
Terminating every thread before a call to std::exit or the exit from main issufficient, but not necessary, to satisfy these requirements. These requirements permit thread managers asstatic-storage-duration objects. — end note ]5Calling the function std::abort() declared in <cstdlib> terminates the program without executing anydestructors and without calling the functions passed to std::atexit() or std::at_quick_exit().3.71Storage duration[basic.stc]Storage duration is the property of an object that defines the minimum potential lifetime of the storagecontaining the object.
The storage duration is determined by the construct used to create the object and isone of the following:— static storage duration— thread storage duration— automatic storage duration— dynamic storage duration2Static, thread, and automatic storage durations are associated with objects introduced by declarations (3.1)and implicitly created by the implementation (12.2).
The dynamic storage duration is associated with objectscreated with operator new (5.3.4).3The storage duration categories apply to references as well. The lifetime of a reference is its storage duration.§ 3.7© ISO/IEC 2011 – All rights reserved65ISO/IEC 14882:2011(E)3.7.1Static storage duration[basic.stc.static]1All variables which do not have dynamic storage duration, do not have thread storage duration, and arenot local have static storage duration. The storage for these entities shall last for the duration of theprogram (3.6.2, 3.6.3).2If a variable with static storage duration has initialization or a destructor with side effects, it shall not beeliminated even if it appears to be unused, except that a class object or its copy/move may be eliminatedas specified in 12.8.3The keyword static can be used to declare a local variable with static storage duration.
[ Note: 6.7 describesthe initialization of local static variables; 3.6.3 describes the destruction of local static variables. — endnote ]4The keyword static applied to a class data member in a class definition gives the data member staticstorage duration.3.7.2Thread storage duration[basic.stc.thread]1All variables declared with the thread_local keyword have thread storage duration. The storage for theseentities shall last for the duration of the thread in which they are created. There is a distinct object orreference per thread, and use of the declared name refers to the entity associated with the current thread.2A variable with thread storage duration shall be initialized before its first odr-use (3.2) and, if constructed,shall be destroyed on thread exit.3.7.3Automatic storage duration[basic.stc.auto]1Block-scope variables explicitly declared register or not explicitly declared static or extern have automatic storage duration. The storage for these entities lasts until the block in which they are createdexits.2[ Note: These variables are initialized and destroyed as described in 6.7.
— end note ]3If a variable with automatic storage duration has initialization or a destructor with side effects, it shall notbe destroyed before the end of its block, nor shall it be eliminated as an optimization even if it appears tobe unused, except that a class object or its copy/move may be eliminated as specified in 12.8.3.7.4Dynamic storage duration[basic.stc.dynamic]1Objects can be created dynamically during program execution (1.9), using new-expressions (5.3.4), anddestroyed using delete-expressions (5.3.5). A C++ implementation provides access to, and managementof, dynamic storage via the global allocation functions operator new and operator new[] and the globaldeallocation functions operator delete and operator delete[].2The library provides default definitions for the global allocation and deallocation functions.
Some globalallocation and deallocation functions are replaceable (18.6.1). A C++ program shall provide at most onedefinition of a replaceable allocation or deallocation function. Any such function definition replaces thedefault version provided in the library (17.6.4.6). The following allocation and deallocation functions (18.6)are implicitly declared in global scope in each translation unit of a program.void* operator new(std::size_t);void* operator new[](std::size_t);void operator delete(void*);void operator delete[](void*);§ 3.7.466© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)These implicit declarations introduce only the function names operator new, operator new[], operator delete, and operator delete[].
[ Note: The implicit declarations do not introduce the names std,std::size_t, or any other names that the library uses to declare these names. Thus, a new-expression,delete-expression or function call that refers to one of these functions without including the header <new>is well-formed. However, referring to std or std::size_t is ill-formed unless the name has been declaredby including the appropriate header. — end note ] Allocation and/or deallocation functions can also bedeclared and defined for any class (12.5).3Any allocation and/or deallocation functions defined in a C++ program, including the default versions inthe library, shall conform to the semantics specified in 3.7.4.1 and 3.7.4.2.3.7.4.1Allocation functions[basic.stc.dynamic.allocation]1An allocation function shall be a class member function or a global function; a program is ill-formed if anallocation function is declared in a namespace scope other than global scope or declared static in globalscope.
The return type shall be void*. The first parameter shall have type std::size_t (18.2). The firstparameter shall not have an associated default argument (8.3.6). The value of the first parameter shall beinterpreted as the requested size of the allocation. An allocation function can be a function template. Sucha template shall declare its return type and first parameter as specified above (that is, template parametertypes shall not be used in the return type and first parameter type).
Template allocation functions shallhave two or more parameters.2The allocation function attempts to allocate the requested amount of storage. If it is successful, it shallreturn the address of the start of a block of storage whose length in bytes shall be at least as large asthe requested size. There are no constraints on the contents of the allocated storage on return from theallocation function. The order, contiguity, and initial value of storage allocated by successive calls to anallocation function are unspecified.
The pointer returned shall be suitably aligned so that it can be convertedto a pointer of any complete object type with a fundamental alignment requirement (3.11) and then usedto access the object or array in the storage allocated (until the storage is explicitly deallocated by a call toa corresponding deallocation function). Even if the size of the space requested is zero, the request can fail.If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from anypreviously returned value p1, unless that value p1 was subsequently passed to an operator delete. Theeffect of dereferencing a pointer returned as a request for zero size is undefined.353An allocation function that fails to allocate storage can invoke the currently installed new-handler function (18.6.2.3), if any.