10

So, I'm aware that in C++ static members can be initialized inside the class if they are a const literal type like the following

class test{ public: static constexpr int stc = 1; private: int a = 0; int b = 0; int c = 0; }; 

and the static constexpr variable stc can be used where the compiler can directly substitute the value of the member i.e

int main () {int array[test::stc];} 

However, if used in a context where the value cannot be directly substituted by the compiler:

int main() { const int &cs = test::stc; } 

then the compiler (clang) generates an error

c++ -std=c++11 -pedantic t.cpp -o t Undefined symbols for architecture x86_64: "test::stc", referenced from: _main in t-a8ee2a.o ld: symbol(s) not found for architecture x86_64 

unless the static member is defined outside the class like so:

constexpr int test::stc;

Why is this the case?

5
  • Which compiler are you using, what compiler error are you getting, and what is the minimal but complete code which triggers that error? Commented Apr 30, 2018 at 23:03
  • @MárioFeroldi updated post with more details Commented Apr 30, 2018 at 23:59
  • 1
    Not sure if this answers your question: Why does a static data member need to be defined outside of the class? Commented May 1, 2018 at 0:02
  • const &cs... gives an error: error: ISO C++ forbids declaration of 'cs' with no type [-fpermissive] Commented May 1, 2018 at 0:39
  • Possible duplicate of constexpr: definition and declaration for constexpr members Commented May 1, 2018 at 1:19

3 Answers 3

6

In

int main() { const int &cs = test::stc; } 

test::stc is odr-used while in

int main () {int array[test::stc];} 

it is not.

The following example from the C++11 Standard supports the above idea.

struct S { static const int x = 0; }; const int &f(const int &r); int n = b ? (1, S::x) // S​::​x is not odr-used here : f(S::x); // S​::​x is odr-used here, so a definition is required 

Looking at it from practical point of view, cs will be an invalid reference unless test::stc has an address. array, on the other hand, needs just the value of test::stc, which can be evaluated at compile time. array does not need the address of test::stc to be a valid object.

An object that is odr-used must be defined exactly once in a program.

Sign up to request clarification or add additional context in comments.

1 Comment

2
static constexpr int stc = 1; // declares the static var constexpr int test::stc; // defines the static var 

for more detailed explanation check link below

http://www.learncpp.com/cpp-tutorial/811-static-member-variables/

Comments

2

C++17 inline variables

In C++17 if you also mark the static member as inline, then I believe that you can odr-use it freely or have multiple definitions across compilation units, e.g.:

#include <iostream> class MyClass { public: inline static constexpr int i = 42; }; int main() { const int &cs = MyClass::i; std::cout << cs << std::endl; std::cout << &MyClass::i << std::endl; } 

More info at: How do inline variables work?

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.