Search code examples
c++classstaticlanguage-lawyerprivate

Why is a private member visible when initializing a static variable?


This compiles:

class Node{
    int m = 0;

    static unsigned f(){
        return 1;
    }

public:
    static unsigned a;
    static unsigned b;
};

unsigned Node::a = sizeof(m); // <= !!!
unsigned Node::b = f();       // <= !!!

int main(){
}

Why? I know sizeof is not function but still, aren't m and f() private?

It is definitely not a bug, because the code compiles on GCC, MSVC, Clang and Intel C++.

Update: Also, note that it is just sizeof(m) and not sizeof(Node::m); same with f() instead of Node::f(). (Koenig's lookup?)


Solution

  • Access to private members is allowed in non-inline definitions of static data members, because the initializer part of the definition (that is, the RHS of the =) is in the scope of the class, according to the Standard ("Note 1", below):

    11.4.9.3 Static Data Members       [class.static.data]


    3   The declaration of a non-inline static data member in its class definition is not a definition and may be of an incomplete type other than cv void.
    [Note 1: The initializer in the definition of a static data member is in the scope of its class ([basic.scope.class]). — end note]


    Note that, in reference to your last (update) paragraph, because the initializer is in the class scope, unqualified/un-scoped variables, such as m and f() in your case, will by default refer to class members (if such exist); so, the f() call in your code is entirely equivalent to Node::f().