Home > Software engineering >  Address of static data member
Address of static data member

Time:11-04

Why C doesn't allow taking the address of a static data member when the data member is initialize within the class and doesn't have an out-of-class definition? How is the storage allocated for static member in this case?

The below minimum program demonstrate the issue.

#include <iostream>

class Test {
public:
    static const int a = 99;   // how is the storage allocated for Test::a??
};

// const int Test::a;

int main() {
    std::cout << Test::a << '\n';  // OK, print 99
    const int* ptr = &Test::a;     // Linker error, undefined reference to Test::a
}

If I uncomment the line const int Test::a, then the program works fine.

CodePudding user response:

This line is a declaration:

static const int a = 99;

It is not a definition. For storage to be allocated, you need a definition. That's where your commented line comes into play.

You can use Test::a even if it has no definition because it is treated as a compile-time constant. In general, a static const T variable (where T is a trivial type) must be usable in a constant expression as soon as it is constant-initialized.

Note that you can get both behaviors (compile-time constant and variable with an address) at the same time:

class Test {
public:
    static const int a = 99;
};

const int Test::a;

template<int i>
struct Templated {};

int main() {
    const int* ptr = &Test::a;
    Templated<Test::a> a;
}

Demo

And to illustrate the constant-initialization point:

class Test {
public:
    static const int a;
};

template<int i>
struct Templated {};

// does not compile because Test::a is *not yet* usable in a constant expression
Templated<Test::a> global;

const int Test::a = 99;

int main() {
    const int* ptr = &Test::a;
    Templated<Test::a> a;
}

Demo

  • Related