Title
Ordering of static reference initialization
Status
cd1
Section
6.9.3.2 [basic.start.static]
Submitter
Mike Miller

Created on 2003-12-01.00:00:00 last changed 25 months ago

Messages

Date: 2005-04-15.00:00:00

[Voted into WP at April 2005 meeting.]

Date: 2005-04-15.00:00:00

[Voted into WP at April 2005 meeting.]

Date: 2022-11-20.07:54:16

Proposed Resolution:

Change 6.9.3.2 [basic.start.static] paragraph 1 as follows:

Objects with static storage duration (3.7.1) shall be zero-initialized (8.5) before any other initialization takes place. Initializing a reference, or an object of POD type, of static storage duration with a constant expression (5.19) is called constant initialization. Together, zero-initialization and constant initialization are Zero-initialization and initialization with a constant expression are collectively called static initialization; all other initialization is dynamic initialization. Static initialization shall be performed Objects of POD types (3.9) with static storage duration initialized with constant expressions (5.19) shall be initialized before any dynamic initialization takes place.
Date: 2022-11-20.07:54:16

I have a couple of questions about 6.9.3.2 [basic.start.static], "Initialization of non-local objects." I believe I recall some discussion of related topics, but I can't find anything relevant in the issues list.

The first question arose when I discovered that different implementations treat reference initialization differently. Consider, for example, the following (namespace-scope) code:

  int i;
  int& ir = i;
  int* ip = &i;
Both initializers, "i" and "&i", are constant expressions, per 7.7 [expr.const] paragraph 4-5 (a reference constant expression and an address constant expression, respectively). Thus, both initializations are categorized as static initialization, according to 6.9.3.2 [basic.start.static] paragraph 1:
Zero-initialization and initialization with a constant expression are collectively called static initialization; all other initialization is dynamic initialization.

However, that does not mean that both ir and ip must be initialized at the same time:

Objects of POD types (3.9) with static storage duration initialized with constant expressions (5.19) shall be initialized before any dynamic initialization takes place.

Because "int&" is not a POD type, there is no requirement that it be initialized before dynamic initialization is performed, and implementations differ in this regard. Using a function called during dynamic initialization to print the values of "ip" and "&ir", I found that g++, Sun, HP, and Intel compilers initialize ir before dynamic initialization and the Microsoft compiler does not. All initialize ip before dynamic initialization. I believe this is conforming (albeit inconvenient :-) behavior.

So, my first question is whether it is intentional that a reference of static duration, initialized with a reference constant expression, need not be initialized before dynamic initialization takes place, and if so, why?

The second question is somewhat broader. As 6.9.3.2 [basic.start.static] is currently worded, it appears that there are no requirements on when ir is initialized. In fact, there is a whole category of objects -- non-POD objects initialized with a constant expression -- for which no ordering is specified. Because they are categorized as part of "static initialization," they are not subject to the requirement that they "shall be initialized in the order in which their definition appears in the translation unit." Because they are not POD types, they are not required to be initialized before dynamic initialization occurs. Am I reading this right?

My preference would be to change 6.9.3.2 [basic.start.static] paragraph 1 so that 1) references are treated like POD objects with respect to initialization, and 2) "static initialization" applies only to POD objects and references. Here's some sample wording to illustrate:

Suggested resolution:

Objects with static storage duration (3.7.1) shall be zero-initialized (8.5) before any other initialization takes place. Initializing a reference, or an object of POD type, of static storage duration with a constant expression (5.19) is called constant initialization. Together, zero-initialization and constant initialization are called static initialization; all other initialization is dynamic initialization. Static initialization shall be performed before any dynamic initialization takes place. [Remainder unchanged.]
History
Date User Action Args
2022-02-18 07:47:23adminsetmessages: + msg6693
2022-02-18 07:47:23adminsetmessages: + msg6692
2008-10-05 00:00:00adminsetstatus: wp -> cd1
2005-10-22 00:00:00adminsetstatus: dr -> wp
2005-05-01 00:00:00adminsetmessages: + msg1186
2005-05-01 00:00:00adminsetstatus: ready -> dr
2004-11-07 00:00:00adminsetstatus: review -> ready
2004-04-09 00:00:00adminsetstatus: open -> review
2003-12-01 00:00:00admincreate