静态数据成员作为C ++默认参数是否安全?

jbo*_*sch 6 c++ initialization

使用静态数据成员作为默认参数值时,我是否需要担心静态初始化顺序的失败?例如:

class Thing {

    static double const default_blarg;  // initialized in another file

    void run(double blarg=default_blarg);

};
Run Code Online (Sandbox Code Playgroud)

我知道default_blarg将在链接时在一个几乎未指定的点初始化,但是我不确定默认参数to何时run初始化。如果是在某个时候default_blarg被初始化过,那么我可以使用哪种方法安全地将默认值作为类接口的一部分公开而不重复呢?使用constexpr静态数据成员可以使其安全吗?

请注意,我知道如果default_blarg不是const ,这可能会产生一些非常令人困惑的行为(这就是原因),并且我也没有尝试使用非静态数据成员。

Nat*_*ica 6

您仍然必须担心静态初始化顺序的失败。假设您有一个a.cpp和b.cpp。在a.cpp中

double const Thing::default_blarg = 0;
Run Code Online (Sandbox Code Playgroud)

现在,在a.cpp中run,此点之后的任何调用都将具有初始化的默认值,您可以继续进行。不幸的是,在b.cpp中,您有另一个静态对象恰巧创建了Thingand 的实例run

现在我们不知道会发生什么。如果b.cpp首先运行,则default_blarg未初始化,并且我们有未定义的行为。

现在给你第二部分

但我不确定要运行的默认参数何时初始化

每次调用函数时都会评估函数的默认参数。因此,只要在default_blarg初始化后调用该函数(如上所述,就可能不会),您就可以了。


R S*_*ahu 5

来自 C++11 标准,第 8.3.6/9 节:

每次调用函数时都会评估默认参数。

只要Thing::default_blargThing::run调用之前初始化,您就应该看到可预测的行为。