|
2433 | 2433 |
|
2434 | 2434 | \pnum
|
2435 | 2435 | \indextext{program!start|(}%
|
2436 |
| -A program shall contain a global function called \tcode{main}, which is the designated |
2437 |
| -start of the program. It is \impldef{defining \tcode{main} in freestanding environment} |
| 2436 | +A program shall contain a global function called \tcode{main}. |
| 2437 | +Executing a program starts a main thread of execution~(\ref{intro.multithread}, \ref{thread.threads}) |
| 2438 | +in which the \tcode{main} function is invoked, |
| 2439 | +and in which variables of static storage duration |
| 2440 | +might be initialized~(\ref{basic.start.static}) and destroyed~(\ref{basic.start.term}). |
| 2441 | +It is \impldef{defining \tcode{main} in freestanding environment} |
2438 | 2442 | whether a program in a freestanding environment is required to define a \tcode{main}
|
2439 | 2443 | function. \begin{note} In a freestanding environment, start-up and termination is
|
2440 | 2444 | \impldef{start-up and termination in freestanding environment}; start-up contains the
|
|
2546 | 2550 | \indextext{initialization!dynamic}%
|
2547 | 2551 | \defn{static initialization};
|
2548 | 2552 | all other initialization is \defn{dynamic initialization}.
|
2549 |
| -Static initialization shall be performed before any dynamic initialization takes place. |
| 2553 | +All static initialization strongly happens before~(\ref{intro.races}) |
| 2554 | +any dynamic initialization. |
2550 | 2555 | \begin{note} The dynamic initialization of non-local variables is described
|
2551 | 2556 | in~\ref{basic.start.dynamic}; that of local static variables is described
|
2552 | 2557 | in~\ref{stmt.dcl}. \end{note}
|
|
2612 | 2617 | \item
|
2613 | 2618 | If \tcode{V} has partially-ordered initialization, \tcode{W} does not have
|
2614 | 2619 | unordered initialization, and \tcode{V} is defined before \tcode{W} in
|
2615 |
| -every translation unit in which \tcode{W} is defined, the initialization of |
2616 |
| -\tcode{V} is sequenced before the initialization of \tcode{W} if the |
2617 |
| -program does not start a thread (\ref{intro.multithread}) and otherwise |
2618 |
| -happens before the initialization of \tcode{W}. |
| 2620 | +every translation unit in which \tcode{W} is defined, then |
| 2621 | +\begin{itemize} |
| 2622 | +\item |
| 2623 | +if the program starts a thread~(\ref{intro.multithread}) |
| 2624 | +other than the main thread~(\ref{basic.start.main}), |
| 2625 | +the initialization of \tcode{V} |
| 2626 | +strongly happens before |
| 2627 | +the initialization of \tcode{W}; |
| 2628 | +\item |
| 2629 | +otherwise, |
| 2630 | +the initialization of \tcode{V} |
| 2631 | +is sequenced before |
| 2632 | +the initialization of \tcode{W}. |
| 2633 | +\end{itemize} |
2619 | 2634 |
|
2620 | 2635 | \item
|
2621 |
| -Otherwise, if a program starts a thread before either \tcode{V} or \tcode{W} is |
2622 |
| -initialized, the initializations of \tcode{V} and \tcode{W} are unsequenced. |
| 2636 | +Otherwise, if the program starts a thread |
| 2637 | +other than the main thread |
| 2638 | +before either \tcode{V} or \tcode{W} is initialized, |
| 2639 | +it is unspecified in which threads |
| 2640 | +the initializations of \tcode{V} and \tcode{W} occur; |
| 2641 | +the initializations are unsequenced if they occur in the same thread. |
2623 | 2642 |
|
2624 | 2643 | \item
|
2625 | 2644 | Otherwise, the initializations of \tcode{V} and \tcode{W} are indeterminately sequenced.
|
|
2629 | 2648 | ordered variables concurrently with another sequence.
|
2630 | 2649 | \end{note}
|
2631 | 2650 |
|
| 2651 | +\pnum |
| 2652 | +\indextext{non-initialization odr-use|see{odr-use, non-initialization}}% |
| 2653 | +A \defnx{non-initialization odr-use}{odr-use!non-initialization} |
| 2654 | +is an odr-use~(\ref{basic.def.odr}) not caused directly or indirectly by |
| 2655 | +the initialization of a non-local static or thread storage duration variable. |
| 2656 | + |
2632 | 2657 | \pnum
|
2633 | 2658 | \indextext{evaluation!unspecified order of}%
|
2634 |
| -It is \impldef{dynamic initialization of static variables before \tcode{main}} whether the |
2635 |
| -dynamic initialization of a non-local non-inline variable with static storage duration |
2636 |
| -happens before the first statement of \tcode{main}. If the initialization is deferred to |
2637 |
| -happen after the first statement of \tcode{main}, it happens before the |
2638 |
| -first odr-use~(\ref{basic.def.odr}) of any non-inline function or non-inline variable |
2639 |
| -defined in the same translation unit as the variable |
2640 |
| -to be initialized.\footnote{A non-local variable with static storage duration |
| 2659 | +It is \impldef{dynamic initialization of static variables before \tcode{main}} |
| 2660 | +whether the dynamic initialization of a |
| 2661 | +non-local non-inline variable with static storage duration |
| 2662 | +is sequenced before the first statement of \tcode{main} or is deferred. |
| 2663 | +If it is deferred, it strongly happens before |
| 2664 | +any non-initialization odr-use |
| 2665 | +of any non-inline function or non-inline variable |
| 2666 | +defined in the same translation unit as the variable to be initialized.% |
| 2667 | +\footnote{A non-local variable with static storage duration |
2641 | 2668 | having initialization
|
2642 |
| -with side effects must be initialized even if it is not |
2643 |
| -odr-used (\ref{basic.def.odr},~\ref{basic.stc.static}).} |
| 2669 | +with side effects is initialized in this case, |
| 2670 | +even if it is not itself odr-used (\ref{basic.def.odr},~\ref{basic.stc.static}).} |
| 2671 | +It is \impldef{threads and program points at which deferred dynamic initialization is performed} |
| 2672 | +in which threads and at which points in the program such deferred dynamic initialization occurs. |
| 2673 | +\begin{note} |
| 2674 | +Such points should be chosen in a way that allows the programmer to avoid deadlocks. |
| 2675 | +\end{note} |
2644 | 2676 | \begin{example}
|
2645 | 2677 | \begin{codeblock}
|
2646 | 2678 | // - File 1 -
|
|
2681 | 2713 | \pnum
|
2682 | 2714 | It is \impldef{dynamic initialization of static inline variables before \tcode{main}}
|
2683 | 2715 | whether the dynamic initialization of a
|
2684 |
| -non-local inline variable with static storage duration happens before the |
2685 |
| -first statement of \tcode{main}. If the initialization is deferred |
2686 |
| -to happen after the first statement of \tcode{main}, it happens before |
2687 |
| -the first odr-use~(\ref{basic.def.odr}) of that variable. |
| 2716 | +non-local inline variable with static storage duration |
| 2717 | +is sequenced before the first statement of \tcode{main} or is deferred. |
| 2718 | +If it is deferred, it strongly happens before |
| 2719 | +any non-initialization odr-use |
| 2720 | +of that variable. |
| 2721 | +It is \impldef{threads and program points at which deferred dynamic initialization is performed} |
| 2722 | +in which threads and at which points in the program such deferred dynamic initialization occurs. |
2688 | 2723 |
|
2689 | 2724 | \pnum
|
2690 | 2725 | It is \impldef{dynamic initialization of thread-local variables before entry}
|
2691 |
| -whether the dynamic initialization of a non-local non-inline variable with static |
2692 |
| -or thread storage duration is sequenced before |
2693 |
| -the first statement of the initial function of the thread. |
2694 |
| -If the initialization is deferred to some point in time sequenced after |
2695 |
| -the first statement of the initial function of the thread, |
2696 |
| -it is sequenced before the first odr-use~(\ref{basic.def.odr}) |
2697 |
| -of any non-inline variable with thread storage duration defined |
2698 |
| -in the same translation unit as the variable to be initialized. |
| 2726 | +whether the dynamic initialization of a |
| 2727 | +non-local non-inline variable with thread storage duration |
| 2728 | +is sequenced before the first statement of the initial function of a thread or is deferred. |
| 2729 | +If it is deferred, |
| 2730 | +the initialization associated with the entity for thread \placeholder{t} |
| 2731 | +is sequenced before the first non-initialization odr-use by \placeholder{t} |
| 2732 | +of any non-inline variable with thread storage duration |
| 2733 | +defined in the same translation unit as the variable to be initialized. |
| 2734 | +It is \impldef{threads and program points at which deferred dynamic initialization is performed} |
| 2735 | +in which threads and at which points in the program such deferred dynamic initialization occurs. |
2699 | 2736 |
|
2700 | 2737 | \pnum
|
2701 | 2738 | If the initialization of a non-local variable with static or thread storage duration
|
|
2711 | 2748 | \indextext{\idxcode{main} function!return from}%
|
2712 | 2749 | Destructors~(\ref{class.dtor}) for initialized objects
|
2713 | 2750 | (that is, objects whose lifetime~(\ref{basic.life}) has begun)
|
2714 |
| -with static storage duration |
2715 |
| -are called as a result of returning from \tcode{main} and as a result of calling |
| 2751 | +with static storage duration, |
| 2752 | +and functions registered with \tcode{std::atexit}, |
| 2753 | +are called as part of a call to |
2716 | 2754 | \indextext{\idxcode{exit}}%
|
2717 | 2755 | \indexlibrary{\idxcode{exit}}%
|
2718 | 2756 | \tcode{std::exit}~(\ref{support.start.term}).
|
| 2757 | +The call to \tcode{std::exit} is sequenced before |
| 2758 | +the invocations of the destructors and the registered functions. |
| 2759 | +\begin{note} |
| 2760 | +Returning from \tcode{main} invokes \tcode{std::exit}~(\ref{basic.start.main}). |
| 2761 | +\end{note} |
| 2762 | + |
| 2763 | +\pnum |
2719 | 2764 | Destructors for initialized objects with thread storage duration within a given thread
|
2720 | 2765 | are called as a result of returning from the initial function of that thread and as a
|
2721 | 2766 | result of that thread calling \tcode{std::exit}.
|
2722 | 2767 | The completions of the destructors for all initialized objects with thread storage
|
2723 |
| -duration within that thread are sequenced before the initiation of the destructors of |
| 2768 | +duration within that thread strongly happen before the initiation of the destructors of |
2724 | 2769 | any object with static storage duration.
|
2725 |
| -If the completion of the constructor or dynamic initialization of an object with thread |
2726 |
| -storage duration is sequenced before that of another, the completion of the destructor |
2727 |
| -of the second is sequenced before the initiation of the destructor of the first. |
| 2770 | + |
| 2771 | +\pnum |
2728 | 2772 | If the completion of the constructor or dynamic initialization of an object with static
|
| 2773 | +storage duration strongly happens before that of another, the completion of the destructor |
| 2774 | +of the second is sequenced before the initiation of the destructor of the first. |
| 2775 | +If the completion of the constructor or dynamic initialization of an object with thread |
2729 | 2776 | storage duration is sequenced before that of another, the completion of the destructor
|
2730 | 2777 | of the second is sequenced before the initiation of the destructor of the first.
|
2731 |
| -\begin{note} This definition permits concurrent destruction. \end{note} If an object is |
| 2778 | +If an object is |
2732 | 2779 | initialized statically, the object is destroyed in the same order as if
|
2733 | 2780 | the object was dynamically initialized. For an object of array or class
|
2734 | 2781 | type, all subobjects of that object are destroyed before any block-scope
|
|
2750 | 2797 | \indextext{\idxcode{atexit}}%
|
2751 | 2798 | \indexlibrary{\idxcode{atexit}}%
|
2752 | 2799 | If the completion of the initialization of an object with static storage
|
2753 |
| -duration is sequenced before a call to \tcode{std::atexit}~(see |
| 2800 | +duration strongly happens before a call to \tcode{std::atexit}~(see |
2754 | 2801 | \tcode{<cstdlib>},~\ref{support.start.term}), the call to the function passed to
|
2755 | 2802 | \tcode{std::atexit} is sequenced before the call to the destructor for the object. If a
|
2756 |
| -call to \tcode{std::atexit} is sequenced before the completion of the initialization of |
| 2803 | +call to \tcode{std::atexit} strongly happens before the completion of the initialization of |
2757 | 2804 | an object with static storage duration, the call to the destructor for the
|
2758 | 2805 | object is sequenced before the call to the function passed to \tcode{std::atexit}. If a
|
2759 |
| -call to \tcode{std::atexit} is sequenced before another call to \tcode{std::atexit}, the |
| 2806 | +call to \tcode{std::atexit} strongly happens before another call to \tcode{std::atexit}, the |
2760 | 2807 | call to the function passed to the second \tcode{std::atexit} call is sequenced before
|
2761 | 2808 | the call to the function passed to the first \tcode{std::atexit} call.
|
2762 | 2809 |
|
|
0 commit comments