在 C++ 中,给定命名空间范围的 const float 依赖于全局 const float,它们的初始化顺序是不是得到保证?

Posted

技术标签:

【中文标题】在 C++ 中,给定命名空间范围的 const float 依赖于全局 const float,它们的初始化顺序是不是得到保证?【英文标题】:In C++, given namespace-wide const float dependant on a global const float, is their initialization order guaranteed?在 C++ 中,给定命名空间范围的 const float 依赖于全局 const float,它们的初始化顺序是否得到保证? 【发布时间】:2018-11-08 08:04:15 【问题描述】:

如果有一对 .h/.cpp 文件分别具有类似的内容,

extern const float ge;

const float ge = 2.2f;

在其中,以及其他类似的 .cpp 文件

namespace 
const float upperLimit = 2.0f * ge;
 // namespace

bool foo(float a)

    return a < upperLimit;

在里面,是否保证upperLimitge之后被初始化?

我知道来自不同翻译单元的全局对象的不确定初始化顺序。我想确定混合全局对象和命名空间范围对象的情况是否属实。

【问题讨论】:

“something like”很模糊,如果你说这正是你要问的会更清楚 全球浮动不止一个,仅此而已。还是您认为它们的确切值很重要? 如果代码是 const float ge = foo(); ,其中 foo 不是 constexpr 函数,则不再保证在 upperLimit 之前初始化。还有很多其他的可能性 【参考方案1】:

在您的代码中,ge 保证在 upperLimit 之前被初始化,但这与命名空间无关。如果您没有命名空间,情况也一样。命名空间对初始化顺序没有影响。

代码const float ge = 2.2f; 是constant initialization 的一部分,constant initialization 是静态初始化的一部分,因为它是一个具有静态存储持续时间的变量,由常量表达式初始化。

然而,在代码const float upperLimit = 2.0f * ge; 中,初始化器不是常量表达式,因为ge 的值是未知的。所以它不是静态初始化(因此属于动态初始化)。

所有静态初始化都发生在动态初始化(C++17 [basic.start.static]/2)之前,所以代码是正确的。

【讨论】:

据我所知浮点初始化不能是静态的,因为浮点表示依赖于平台,所以它必须动态初始化,如果我错了,请纠正我。 @VictorChe 我已经链接到 cppreference 页面。浮点常量是常量表达式,see here also 非常感谢。

以上是关于在 C++ 中,给定命名空间范围的 const float 依赖于全局 const float,它们的初始化顺序是不是得到保证?的主要内容,如果未能解决你的问题,请参考以下文章

整个类范围内的 C++ 命名空间别名

为啥 C++ 友元类只需要在其他命名空间中进行前向声明?

C++入门(命名空间,缺省参数,函数重载,引用,内联函数,auto,范围for)

const和define()的区别

c++中Std有啥用

static关键字在命名空间范围内没用吗?