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?

Sohail Si
  • 2,376
  • 2
  • 20
  • 33

2 Answers2

9

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
}
Anoop Rana
  • 19,715
  • 4
  • 12
  • 33
  • 3
    Got my vote for mentioning `inline`. I tend to forget that version :-) – Ted Lyngmo Apr 16 '22 at 09:03
  • 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. – Sohail Si Apr 16 '22 at 09:04
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
}
Ted Lyngmo
  • 60,763
  • 5
  • 37
  • 77
  • Excellent. So, how was it working before? Is it a new requirement in recent updates of C++? – Sohail Si Apr 16 '22 at 08:55
  • 2
    @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. – Ted Lyngmo Apr 16 '22 at 08:56