2

The static class member static_member not recognised in the following code.

However, it works on older versions of the compiler. The compiler I use is based on clang.

class my_class { public: static int static_member; }; int main() { my_class::static_member = 0; } 

To reproduce the error, save above file as c1.cpp and run:

VER_TAG=latest # or VER_TAG=3.1.8 docker run --rm -v $(pwd):/src emscripten/emsdk::$VER_TAG emcc /src/c1.cpp 

Leads to error:

wasm-ld: error: /tmp/emscripten_temp_o3wmmq8k/c1_0.o: undefined symbol: my_class::static_member

However, if I use VER_TAG=2.0.22 (earlier release of the compiler), it works fine.

Is there anything wrong with my code? Or is it related to compiler implementation?

1
  • 1
    Change it to: int my_class::static_member = 0; and move the definition outside main function. Commented Apr 16, 2022 at 8:52

2 Answers 2

8

From static data member's definition's documentation:

The declaration inside the class body is not a definition and may declare the member to be of incomplete type (other than void), including the type in which the member is declared.

So we have to first provide an out-of class definition for the static data member as shown below:

class my_class { public: static int static_member;//this is a declaration }; int my_class::static_member = 0;//this is a definition int main() { std::cout<<my_class::static_member<<std::endl; } 

From C++17 onwards we can use inline keyword so that we'll not need an out-of-class definition for the static data member anymore:

class my_class { public: inline static int static_member = 0; // this is a definition }; //nothing needed here int main() { std::cout<<my_class::static_member; // use the static_member here } 
Sign up to request clarification or add additional context in comments.

3 Comments

Got my vote for mentioning inline. I tend to forget that version :-)
Great. I will tag @ted-lyngmo as accepted answer only because he answered earlier. Thanks for the extra education by mentioning "out-of class definition" and the new inline usage.
@jason-liam Use of inline is a neat solution. Thanks for mentioning that.
5

Is there anything wrong with my code?

Yes, your static_member doesn't have a definition.

class my_class { public: static int static_member; // declaration }; int my_class::static_member{}; // missing definition int main() { my_class::static_member = 0; // now you can use it here } 

4 Comments

Excellent. So, how was it working before? Is it a new requirement in recent updates of C++?
@SohailSi I think your older linker had a flaw that didn't detect this missing definition - or perhaps the compiler somehow added a definition by itself for some reason.
Not sure which one to choose as the chosen answer: Your last comment is great: it explained the "cause" of the problem (and confusion). The other answer gave the "solution" for the problem (inline).
@SohailSi Yes, inline is one way to solve it from C++17. Prior to C++17, you had to do it like I showed in my answer (which still works btw).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.