Static Variables Initialization Quiz
Asked Answered
S

1

16
#include <stdio.h>

class C
{
   public:
          static int i;
          static int j;
};

int i = 10;
int C::i = 20;
int C::j = i + 1;

int main ()
{
    printf("%d", C::j);

    return 0;
}

What is the value of: C::j

I was reading a c++ quiz and came across the following question. I thought that the answer is 11.

int C::j = i + 1;

Since it is accessing the non static i which is 10? So, I thought 11 should be the answer?

I compiled and ran this code through visual studio and it prints 21. Which is confusing to me. Can someone please explain why this is happening? What am I missing?

Silencer answered 2/9, 2015 at 20:53 Comment(5)
One of the reasons I hate C++. In an "ideal world", if you say "i", you get "i". Instead of the stupid language second-guessing and giving you "C::i" instead. I believe the workaround - if you want "10" - is to qualify int C::j = ::i + 1;.Tried
Yea, I knew I could use ::i to be explicit but I did not think I needed to.Silencer
The language isn't second-guessing anything. This behaviour is the same as the behaviour of defining functions out-of-line. Inside the body of a function of C you would not want to type C::i every time you meant the member, would you?Sexennial
@Brian Although, that would simplify things a lot if you always had to write this->member.Sessler
@Brian Coming from a Python background: yes. Yes I would. Except C is the name of a class, and what I really want is the name of the instance. So this-> is...almost what I want, except -> is a lot more awkward than ..Paxton
S
24

[basic.lookup.qual]/3

In a declaration in which the declarator-id is a qualified-id, names used before the qualified-id being declared are looked up in the defining namespace scope; names following the qualified-id are looked up in the scope of the member’s class or namespace.

In

int C::j = i + 1;

the declarator-id, i.e., the name of the entity being declared, is C::j, which is a qualified-id. Therefore, the i following it is looked up in the scope of C, and refers to C::i.

Less technically, when you define a static data member, the initializer can be thought of as being in the scope of the class, and will find class members before globals.

This is the same rule that ensures that when a member function is defined out-of-line, names after the name of the function will be looked up in class scope and won't require explicit qualification if they refer to class members. It is more unusual seeing this being applied to definitions of static data members, but it is perfectly consistent.

Sexennial answered 2/9, 2015 at 20:56 Comment(1)
Should probably add why C::j necessarily gets initialized after C::i, so it's definitely 21 and not 1.Sessler

© 2022 - 2024 — McMap. All rights reserved.