静态数据成员作为C ++默认参数是否安全? [英] Are static data members safe as C++ default arguments?

查看:87
本文介绍了静态数据成员作为C ++默认参数是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Do I need to worry about the static initialization order fiasco when using a static data member as a default argument value? For example:

class Thing {

    static double const default_blarg;  // initialized in another file

    void run(double blarg=default_blarg);

};

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

I know default_blarg will be initialized at a mostly-unspecified point at link time, but I'm not sure when the default argument to run is initialized. If it's at some point that could be before default_blarg is initialized, what approach could I use to safely expose the default value as part of the class interface without repeating it? Would using constexpr for the static data member make it safe?

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

Note that I'm aware that this could yield some very confusing behavior if default_blarg wasn't const (that's why it is), and I'm not trying to use a non-static data member.

推荐答案

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

You still have to be worried about the static initialization order fiasco. Lets say you have a.cpp and b.cpp. In a.cpp you have

double const Thing::default_blarg = 0;

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

Now in a.cpp any call to run after this point will have a initialized default and you are good to go. Unfortunately in b.cpp you have another static object that happens to create an instance of Thing and call run.

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

Now we do not know what will happen. If b.cpp runs first then default_blarg is not initialized and we have undefined behavior.

现在为您提供第二部分

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

but I'm not sure when the default argument to run is initialized

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

The default arguments of a function are evaluated each time the function is called. So as long as the function is called after default_blarg is initialized(and as noted above it may not) you will be okay.

这篇关于静态数据成员作为C ++默认参数是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆