Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Address of static data member

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

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

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading