static class 成员无法识别但仅适用于新版本的 C++ 编译

static class member not recognised but only for new versions of C++ compile

以下代码无法识别静态 class 成员 static_member

但是,它适用于旧版本的编译器。我使用的编译器是基于clang.

class my_class {
  public:
    static int static_member;
};

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

要重现错误,请将上述文件另存为 c1.cpp 和 运行:

VER_TAG=latest # or VER_TAG=3.1.8

docker run --rm -v $(pwd):/src emscripten/emsdk::$VER_TAG emcc /src/c1.cpp

导致错误:

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

但是,如果我使用 VER_TAG=2.0.22(编译器的早期版本),它工作正常。

我的代码有什么问题吗?还是跟编译器实现有关?

Is there anything wrong with my code?

是的,您的 static_member 没有定义。

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
}

来自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.

所以我们必须首先为静态数据成员提供out-ofclass定义,如下所示:

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;
}

从 C++17 开始,我们可以使用 inline 关键字,这样我们就不再需要静态数据成员的 out-of-class 定义了:

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
}