内联初始化的静态 const 类成员的初始化顺序保证



假设我有一个static const int类成员变量。它直接在类定义中初始化,但它在.cpp中没有定义(这没关系,因为它没有使用 odr(。

此外,假设此常量用于另一个类的构造函数初始值设定项列表中,并且创建了该另一个类的全局实例。

// mytype1.hpp
class MyType1
{
public:
static const int g_myConstant = 42; // no definition in cpp
};
// mytype2.hpp
class MyType2
{
public:
MyType2();
private:
int m_myMember;
};
// mytype2.cpp
MyType2::MyType2()
: m_myMember(MyType1::g_myConstant)
{
}
// otherfile.cpp
// is the reference to MyType1::g_myConstant in the ctor well defined?
MyType2 myType2GlobalInstance;

myType2GlobalInstance的构造是否定义明确?换句话说:C++对类成员变量的静态初始化顺序有什么保证static const

由于没有该常量的定义,因此可能没有需要初始化的内存,并且变量的行为更像预处理器宏......但这能保证吗?是否定义了常量有什么区别吗?

如果成员变量static constexpr,它会改变任何东西吗?

对于静态初始化,在 C++14 之前,零初始化发生在常量初始化之前。自 C++14 起,将发生常量初始化而不是零初始化。常量初始化基本上发生在由常量表达式(或 constexpr 构造函数(进行值初始化的对象和引用上。详情请见此处。

如果编译器可以保证该值与遵循标准初始化顺序相同,则允许编译器使用常量初始化初始化来初始化其他静态对象。在实践中,常量初始化在编译时执行,预先计算的对象表示形式存储为程序映像的一部分。如果编译器不这样做,它仍然必须保证在任何动态初始化之前进行此初始化。

m_myMember不是静态初始化的,因为它的类构造函数不是constexprg_myConstant是常量初始化的。使用static constexpr强制编译器在编译器时初始化值,没有constexpr,编译器可以在编译时初始化。您的构造定义明确。

从 cppreference 看这个例子:

#include <iostream>
#include <array>
struct S {
static const int c;
};
const int d = 10 * S::c; // not a constant expression: S::c has no preceding
// initializer, this initialization happens after const
const int S::c = 5;      // constant initialization, guaranteed to happen first
int main()
{
std::cout << "d = " << d << 'n';
std::array<int, S::c> a1; // OK: S::c is a constant expression
//  std::array<int, d> a2;    // error: d is not a constant expression
}

但是现在,如果我们改变初始化顺序,它会编译:

#include <iostream>
#include <array>
struct S {
static const int c;
};
//both inits are now constant initialization
const int S::c = 5;
const int d = 10 * S::c;
int main()
{
std::cout << "d = " << d << 'n';
std::array<int, S::c> a1;
std::array<int, d> a2; //now, it's ok
}

相关内容

  • 没有找到相关文章

最新更新