Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[basic.start.static] p3 is a bit vague #4800

Closed
xmh0511 opened this issue Aug 10, 2021 · 9 comments
Closed

[basic.start.static] p3 is a bit vague #4800

xmh0511 opened this issue Aug 10, 2021 · 9 comments
Labels
cwg Issue must be reviewed by CWG.

Comments

@xmh0511
Copy link
Contributor

xmh0511 commented Aug 10, 2021

An implementation is permitted to perform the initialization of a variable with static or thread storage duration as a static initialization even if such initialization is not required to be done statically, provided that

  • the dynamic version of the initialization does not change the value of any other object of static or thread storage duration prior to its initialization, and
  • the static version of the initialization produces the same value in the initialized variable as would be produced by the dynamic initialization if all variables not required to be initialized statically were initialized dynamically.
inline double fd() { return 1.0; }
extern double d1;
double d2 = d1;     // unspecified:
                    // either statically initialized to 0.0 or
                    // dynamically initialized to 0.0 if d1 is
                    // dynamically initialized, or 1.0 otherwise
double d1 = fd();   // either initialized statically or dynamically to 1.0

The dynamic initialization of d2 can be finely interpreted. However, consider the case, static initialization of d2, when [basic.start.static] p3 applies.

The dynamic initialization of d2 would be 0 if d2 and d1 are all dynamically initialized(since the zero-initialization occurs prior to any dynamic initialization). However, why could we guarantee that the value of d2 statically initialized from d1 is definitely 0? In other words, why is the value of the initializer d1 zero when it participates in the static initialization at that point? This implies the static initialization(zero-initialization) of d1 must happen before the static initialization of d2(d2 is statically initialized from d1).

@jensmaurer
Copy link
Member

"static initialization" is defined as zero-initialization or constant-initialization. Which means we have to check whether
double d2 = x;
satisfies the conditions given in the quoted text. Which it does for x == 0 only, I believe, so double d2 = 0; is a valid static initialization for the above snippet.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Aug 20, 2021

I think "the static version of the initialization" is saying that d2 is statically initialized from x, which should have been a dynamic initialization.

double d1 = fd(); // either initialized statically or dynamically to 1.0

Regardless of static or dynamic initialization of d1, they all have the value 1.0 that is the result of the initializer fd(). Anyhow, the static version of d2 requires that the static initialization(i.e., zero-initialization) of x shall occur prior to its static initialization. The standard indeed does not specify the order of static initialization, hence, it leaves room for this possibility? Is it a correct interpretation of this issue?

@jensmaurer
Copy link
Member

jensmaurer commented Aug 20, 2021

There is no separate concept "statically initialized"; it just means "static initialization". And "static initialization" can't read other data, but just deal in (compile-time) constants, so an ordering problem does not arise (which is the primary motivation for static initialization).

It's a valid initialization order "d1 zero-init, then d2 dynamically initialized from d1, then d1 dynamically initialized from fd()" so the transformation "d2 = 0" is valid (i.e. means zero-initialization of d2).

@xmh0511
Copy link
Contributor Author

xmh0511 commented Aug 20, 2021

It's a valid initialization order "d1 zero-init, then d2 dynamically initialized from d1, then d1 dynamically initialized from fd()"
This has implied that the static initialization of d1 must order prior to the (transformed) static initialization of d2(i.e. means zero-initialization of d2), Isn't it?

d1 is zero-initialization  // this happens before the transformed static initialization of d2
double  d2 = d1;  // original dynamic initialization, turned to static initialization, 
                        //   which means the value of `d1` at this point is 0

It seems the initialization must perform in this order, then the conditions will be satisfied.

I think the transformation does not mean transform the original dynamic initialization to be merely a zero-initialization, Instead, I think the intent is saying transform the dynamic initialization to be a constant initialization if these conditions would be true. double d1 = fd(); // either initialized statically or dynamically to 1.0 proves this opinion. The comment says d1 may be statically initialized to 1.0 where the value 1.0 is read from fd().

@jensmaurer
Copy link
Member

jensmaurer commented Aug 20, 2021

Again, static initialization (which includes constant initialization) does not read the value of d1, so there is no ordering concern here. Any argument that talks about static initialization somehow reading d1 is incorrect.

The idea is: If there is a valid combination of static and dynamic initialization for all variables in view resulting in some initial values for the variables and the conditions are satisfied, then a particular dynamic initialization may instead be performed as static initialization if the resulting initial values are the same as for that particular combination.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Aug 20, 2021

According to your clarification, I think if add an additional wording would make the meaning clearer.

An implementation is permitted to perform the initialization of a variable with static or thread storage duration as a static initialization even if such initialization is not required to be done statically, provided that

  • [...]
  • [...]

Constant initialization from the value will replace the dynamic initialization as the static initialization.

The concern is basic on what is the static version of the initialization. Does it mean the dynamic initialization would be viewed as a static initialization(which requires reading the value of the initializer) to be performed or mean a complete new static initialization generated by the implementation if conditions are satisfied(as if the initializer were replaced to a constant value)? IIUC, You clarify it to be the latter. Since if the initializer is a glvalue, lvalue-to-rvalue conversion(read value) shall be applied to it in order to perform initialization as per [dcl.init#general-15.9] and [basic.lval#1.2], hence what would the initializer be is significant when we talk about that initialization.

@jensmaurer
Copy link
Member

An lvalue-to-rvalue conversion on a global non-const variable would violate [expr.const] and thus not be static initialization. Thus, that can't possibly be meant.

@jensmaurer jensmaurer added the decision-required A decision of the editorial group (or the Project Editor) is required. label Aug 20, 2021
@xmh0511
Copy link
Contributor Author

xmh0511 commented Aug 24, 2021

So, I think we should clarify what is the initializer expression in the transformed static version initialization. Since we always have a prvalue to perform the initialization. Maybe, the value consisted with the dynamic initialization could be interpreted as a constant-expression to perform that static initialization.

@tkoeppe tkoeppe added the cwg Issue must be reviewed by CWG. label Jun 12, 2023
@jensmaurer jensmaurer removed the decision-required A decision of the editorial group (or the Project Editor) is required. label Nov 7, 2023
@jensmaurer
Copy link
Member

This might be addressed by CWG2821.

@jensmaurer jensmaurer closed this as not planned Won't fix, can't repro, duplicate, stale Nov 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cwg Issue must be reviewed by CWG.
Projects
None yet
Development

No branches or pull requests

3 participants