|
2432 | 2432 |
|
2433 | 2433 | \pnum
|
2434 | 2434 | \indextext{program!start|(}%
|
2435 |
| -A program shall contain a global function called \tcode{main}, which is the designated |
2436 |
| -start of the program. It is \impldef{defining \tcode{main} in freestanding environment} |
| 2435 | +A program shall contain a global function called \tcode{main}. |
| 2436 | +Executing a program starts a main thread of execution~(\ref{intro.multithread}, \ref{thread.threads}) |
| 2437 | +in which the \tcode{main} function is invoked, |
| 2438 | +and in which variables of static storage duration |
| 2439 | +might be initialized~(\ref{basic.start.static}) and destroyed~(\ref{basic.start.term}). |
| 2440 | +It is \impldef{defining \tcode{main} in freestanding environment} |
2437 | 2441 | whether a program in a freestanding environment is required to define a \tcode{main}
|
2438 | 2442 | function. \begin{note} In a freestanding environment, start-up and termination is
|
2439 | 2443 | \impldef{start-up and termination in freestanding environment}; start-up contains the
|
|
2559 | 2563 | \indextext{initialization!dynamic}%
|
2560 | 2564 | \defn{static initialization};
|
2561 | 2565 | all other initialization is \defn{dynamic initialization}.
|
2562 |
| -Static initialization shall be performed before any dynamic initialization takes place. |
| 2566 | +All static initialization strongly happens before~(\ref{intro.races}) |
| 2567 | +any dynamic initialization. |
2563 | 2568 | \begin{note} The dynamic initialization of non-local variables is described
|
2564 | 2569 | in~\ref{basic.start.dynamic}; that of local static variables is described
|
2565 | 2570 | in~\ref{stmt.dcl}. \end{note}
|
|
2627 | 2632 | unordered initialization, and \tcode{V} is defined before \tcode{W} in
|
2628 | 2633 | every translation unit in which \tcode{W} is defined, the initialization of
|
2629 | 2634 | \tcode{V} is sequenced before the initialization of \tcode{W} if the
|
2630 |
| -program does not start a thread (\ref{intro.multithread}) and otherwise |
2631 |
| -happens before the initialization of \tcode{W}. |
| 2635 | +program does not start a thread~(\ref{intro.multithread}) |
| 2636 | +other than the main thread~(\ref{basic.start.main}) |
| 2637 | +and otherwise strongly happens before the initialization of \tcode{W}. |
2632 | 2638 |
|
2633 | 2639 | \item
|
2634 |
| -Otherwise, if a program starts a thread before either \tcode{V} or \tcode{W} is |
2635 |
| -initialized, the initializations of \tcode{V} and \tcode{W} are unsequenced. |
| 2640 | +Otherwise, if the program starts a thread |
| 2641 | +other than the main thread |
| 2642 | +before either \tcode{V} or \tcode{W} is initialized, |
| 2643 | +it is unspecified in which threads |
| 2644 | +the initializations of \tcode{V} and \tcode{W} occur; |
| 2645 | +the initializations are unsequenced if they occur in the same thread. |
2636 | 2646 |
|
2637 | 2647 | \item
|
2638 | 2648 | Otherwise, the initializations of \tcode{V} and \tcode{W} are indeterminately sequenced.
|
|
2642 | 2652 | ordered variables concurrently with another sequence.
|
2643 | 2653 | \end{note}
|
2644 | 2654 |
|
| 2655 | +\pnum |
| 2656 | +\indextext{non-initialization odr-use|see{odr-use, non-initialization}}% |
| 2657 | +A \defnx{non-initialization odr-use}{odr-use!non-initialization} |
| 2658 | +is an odr-use~(\ref{basic.def.odr}) not caused directly or indirectly by |
| 2659 | +the initialization of a non-local static or thread storage duration variable. |
| 2660 | + |
2645 | 2661 | \pnum
|
2646 | 2662 | \indextext{evaluation!unspecified order of}%
|
2647 |
| -It is \impldef{dynamic initialization of static variables before \tcode{main}} whether the |
2648 |
| -dynamic initialization of a non-local non-inline variable with static storage duration |
2649 |
| -happens before the first statement of \tcode{main}. If the initialization is deferred to |
2650 |
| -happen after the first statement of \tcode{main}, it happens before the |
2651 |
| -first odr-use~(\ref{basic.def.odr}) of any non-inline function or non-inline variable |
2652 |
| -defined in the same translation unit as the variable |
2653 |
| -to be initialized.\footnote{A non-local variable with static storage duration |
| 2663 | +It is \impldef{dynamic initialization of static variables before \tcode{main}} |
| 2664 | +whether the dynamic initialization of a |
| 2665 | +non-local non-inline variable with static storage duration |
| 2666 | +is sequenced before the first statement of \tcode{main} or is deferred. |
| 2667 | +If it is deferred, it strongly happens before |
| 2668 | +any non-initialization odr-use |
| 2669 | +of any non-inline function or non-inline variable |
| 2670 | +defined in the same translation unit as the variable to be initialized.% |
| 2671 | +\footnote{A non-local variable with static storage duration |
2654 | 2672 | having initialization
|
2655 |
| -with side effects must be initialized even if it is not |
2656 |
| -odr-used (\ref{basic.def.odr},~\ref{basic.stc.static}).} |
| 2673 | +with side effects is initialized in this case |
| 2674 | +even if it is not itself odr-used (\ref{basic.def.odr},~\ref{basic.stc.static}).} |
| 2675 | +It is \impldef{threads and program points at which deferred dynamic initialization is performed} |
| 2676 | +in which threads and at which points in the program such deferred dynamic initialization occurs. |
| 2677 | +\begin{note} |
| 2678 | +Such points should be chosen in a way that allows the programmer to avoid deadlocks. |
| 2679 | +\end{note} |
2657 | 2680 | \begin{example}
|
2658 | 2681 | \begin{codeblock}
|
2659 | 2682 | // - File 1 -
|
|
2694 | 2717 | \pnum
|
2695 | 2718 | It is \impldef{dynamic initialization of static inline variables before \tcode{main}}
|
2696 | 2719 | whether the dynamic initialization of a
|
2697 |
| -non-local inline variable with static storage duration happens before the |
2698 |
| -first statement of \tcode{main}. If the initialization is deferred |
2699 |
| -to happen after the first statement of \tcode{main}, it happens before |
2700 |
| -the first odr-use~(\ref{basic.def.odr}) of that variable. |
| 2720 | +non-local inline variable with static storage duration |
| 2721 | +is sequenced before the first statement of \tcode{main} or is deferred. |
| 2722 | +If it is deferred, it strongly happens before |
| 2723 | +any non-initialization odr-use |
| 2724 | +of that variable. |
| 2725 | +It is \impldef{threads and program points at which deferred dynamic initialization is performed} |
| 2726 | +in which threads and at which points in the program such deferred dynamic initialization occurs. |
2701 | 2727 |
|
2702 | 2728 | \pnum
|
2703 | 2729 | It is \impldef{dynamic initialization of thread-local variables before entry}
|
2704 |
| -whether the dynamic initialization of a non-local non-inline variable with static |
2705 |
| -or thread storage duration is sequenced before |
2706 |
| -the first statement of the initial function of the thread. |
2707 |
| -If the initialization is deferred to some point in time sequenced after |
2708 |
| -the first statement of the initial function of the thread, |
2709 |
| -it is sequenced before the first odr-use~(\ref{basic.def.odr}) |
2710 |
| -of any non-inline variable with thread storage duration defined |
2711 |
| -in the same translation unit as the variable to be initialized. |
| 2730 | +whether the dynamic initialization of a |
| 2731 | +non-local non-inline variable with thread storage duration |
| 2732 | +is sequenced before the first statement of the initial function of a thread or is deferred. |
| 2733 | +If it is deferred, |
| 2734 | +the initialization associated with the entity for thread \placeholder{t} |
| 2735 | +is sequenced before the first non-initialization odr-use by \placeholder{t} |
| 2736 | +of any non-inline variable with thread storage duration |
| 2737 | +defined in the same translation unit as the variable to be initialized. |
| 2738 | +It is \impldef{threads and program points at which deferred dynamic initialization is performed} |
| 2739 | +in which threads and at which points in the program such deferred dynamic initialization occurs. |
2712 | 2740 |
|
2713 | 2741 | \pnum
|
2714 | 2742 | If the initialization of a non-local variable with static or thread storage duration
|
|
2724 | 2752 | \indextext{\idxcode{main} function!return from}%
|
2725 | 2753 | Destructors~(\ref{class.dtor}) for initialized objects
|
2726 | 2754 | (that is, objects whose lifetime~(\ref{basic.life}) has begun)
|
2727 |
| -with static storage duration |
2728 |
| -are called as a result of returning from \tcode{main} and as a result of calling |
| 2755 | +with static storage duration, |
| 2756 | +and functions registered with \tcode{std::atexit}, |
| 2757 | +are called as part of a call to |
2729 | 2758 | \indextext{\idxcode{exit}}%
|
2730 | 2759 | \indexlibrary{\idxcode{exit}}%
|
2731 | 2760 | \tcode{std::exit}~(\ref{support.start.term}).
|
| 2761 | +The call to \tcode{std::exit} is sequenced before |
| 2762 | +the invocations of the destructors and the registered functions. |
| 2763 | +\begin{note} |
| 2764 | +Returning from \tcode{main} invokes \tcode{std::exit}~(\ref{basic.start.main}). |
| 2765 | +\end{note} |
| 2766 | + |
| 2767 | +\pnum |
2732 | 2768 | Destructors for initialized objects with thread storage duration within a given thread
|
2733 | 2769 | are called as a result of returning from the initial function of that thread and as a
|
2734 | 2770 | result of that thread calling \tcode{std::exit}.
|
2735 | 2771 | The completions of the destructors for all initialized objects with thread storage
|
2736 |
| -duration within that thread are sequenced before the initiation of the destructors of |
| 2772 | +duration within that thread strongly happen before the initiation of the destructors of |
2737 | 2773 | any object with static storage duration.
|
2738 |
| -If the completion of the constructor or dynamic initialization of an object with thread |
2739 |
| -storage duration is sequenced before that of another, the completion of the destructor |
2740 |
| -of the second is sequenced before the initiation of the destructor of the first. |
| 2774 | + |
| 2775 | +\pnum |
2741 | 2776 | If the completion of the constructor or dynamic initialization of an object with static
|
| 2777 | +storage duration strongly happens before that of another, the completion of the destructor |
| 2778 | +of the second is sequenced before the initiation of the destructor of the first. |
| 2779 | +If the completion of the constructor or dynamic initialization of an object with thread |
2742 | 2780 | storage duration is sequenced before that of another, the completion of the destructor
|
2743 | 2781 | of the second is sequenced before the initiation of the destructor of the first.
|
2744 |
| -\begin{note} This definition permits concurrent destruction. \end{note} If an object is |
| 2782 | +If an object is |
2745 | 2783 | initialized statically, the object is destroyed in the same order as if
|
2746 | 2784 | the object was dynamically initialized. For an object of array or class
|
2747 | 2785 | type, all subobjects of that object are destroyed before any block-scope
|
|
2763 | 2801 | \indextext{\idxcode{atexit}}%
|
2764 | 2802 | \indexlibrary{\idxcode{atexit}}%
|
2765 | 2803 | If the completion of the initialization of an object with static storage
|
2766 |
| -duration is sequenced before a call to \tcode{std::atexit}~(see |
| 2804 | +duration strongly happens before a call to \tcode{std::atexit}~(see |
2767 | 2805 | \tcode{<cstdlib>},~\ref{support.start.term}), the call to the function passed to
|
2768 | 2806 | \tcode{std::atexit} is sequenced before the call to the destructor for the object. If a
|
2769 |
| -call to \tcode{std::atexit} is sequenced before the completion of the initialization of |
| 2807 | +call to \tcode{std::atexit} strongly happens before the completion of the initialization of |
2770 | 2808 | an object with static storage duration, the call to the destructor for the
|
2771 | 2809 | object is sequenced before the call to the function passed to \tcode{std::atexit}. If a
|
2772 |
| -call to \tcode{std::atexit} is sequenced before another call to \tcode{std::atexit}, the |
| 2810 | +call to \tcode{std::atexit} strongly happens before another call to \tcode{std::atexit}, the |
2773 | 2811 | call to the function passed to the second \tcode{std::atexit} call is sequenced before
|
2774 | 2812 | the call to the function passed to the first \tcode{std::atexit} call.
|
2775 | 2813 |
|
|
0 commit comments