Are variables considered defined while calculation of their initialization value?
Asked Answered
S

2

5

This is my small program:

enum Type
{
    b = 1,
    c = 2
};

int main()
{
    Type b = b;
    std::cout << b << std::endl;

    return 0;
}

Which outputs 0. Can I conclude that the above definition consists of this sequential steps?

  1. Declaration of b as variable of type Type
  2. Definition of that variable and initialization with 0 default value
  3. Evaluation of it's new value, which includes the variable itself (with value 0)
  4. Assigning that new value to variable.

And, do variables get initialized with 0 always, even if they are explicitly initialized?

My second question is - if it uses the variable in it's initialization list in specified example, why then I don't get error about ambiguity? Is compiler trying to find b in the variable list first, and only then checks for declared enumeration?

Sickly answered 12/6, 2016 at 9:5 Comment(2)
Don't do that. You'll just confuse yourself and anyone who has to maintain that code, which includes you in the future.Crissie
Sure, you are right! I just tried to understand the logic of language in that example.Sickly
U
7

Step 1 is correct, but the rest is wrong. What happens is that the variable b is defined and immediately initialized to the value of the variable b. This leads to undefined behavior because b is not initialized before it's used in its own initialization.

If you want to initialize it to Type::b then you need to explicitly write that:

Type b = Type::b;
Upon answered 12/6, 2016 at 9:11 Comment(4)
Got it. And why it uses uninitialized variable instead of Type::b by default?Sickly
@MisterNobody b is in scope as soon as the = is reachedPutrefy
Yes, but my question is different. Consider Type b; b = b; code, why in the assignment the variable is being used, instead of Type::b?Sickly
the name is looked up in the innermost scope, only looks in outer scopes if not foundPutrefy
W
1

Although the variable is considered defined during its own initialization, it is still illegal to evaluate it unit its initialization is complete. That is why Type b = b is undefined behavior.

The reason why the variable is even defined is so that you could do this:

struct X {
    int *p;
    int a;
};
X x = {&x.a, 123};
cout << *x.p << endl;

Using the variable being initialized for purposes other than its own evaluation is legal. In the example above, the initializer of x must be able to refer to x in order to compute the address of its a member. This is legal, because a itself is not evaluated (demo).

Winni answered 12/6, 2016 at 9:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.