In C++, given namespace-wide const float dependant on a global const float, is their initialization order guaranteed?

If there is a pair of .h/.cpp files with something like, respectively,

extern const float ge;

and

const float ge = 2.2f;

in them, and the other .cpp file with something like

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

bool foo(float a)
{
    return a < upperLimit;
}

in it, is it guaranteed that upperLimit is initialized after the ge?

I'm aware about indefinite initialization order of global objects from different translation units. I'd like to be sure if it is true for the case of mixed global and namespace-wide objects.

1 answer

  • answered 2018-11-08 08:17 M.M

    In your code, ge is guaranteed to be initialized before upperLimit but this is nothing to do with namespaces. The case would be the same if you didn't have the namespace. Namespaces have no effect on initialization order.

    The code const float ge = 2.2f; is part of constant initialization, which is part of static initialization, because it is a variable with static storage duration being initialized by a constant expression.

    However, in the code const float upperLimit = 2.0f * ge;, the initializer is NOT a constant expression because the value of ge is not known. So it is not static initialization (and therefore falls under dynamic initialization).

    All static initialization strongly happens before dynamic initialization (C++17 [basic.start.static]/2) so the code is correct.