how to guarantee initilization of a stack variable with a compile time constant

Solution 1:

I am simply wondering why constinit is limited to static variables. For my[sic] it makes not much sense.

Constant initialization and dynamic initialization are concepts that apply only to objects with static storage duration. The constinit specifier merely means to enforce our expectation that a variable will undergo the former, rather than the latter. It's not an optimization tool, but a way to codify how our code is meant to behave. Without it, dynamic initialization can happen silently, and as any C++ programmer who has been around the block can tell you, that also means the static initialization order fiasco can occur.

With constinit, we either get the expected behavior or a diagnostic. It doesn't apply to automatic variables because they don't suffer from the same problem static variables do.

But if you want to ensure i is initialized by something that can be constant evaluated, then it's not too hard to accomplish.

template<auto result> consteval auto const_eval() { return result; }

int main()
{
     int i = const_eval<func(8)>();
     i = 9;
}

If func(8) cannot be constant evaluated, it's a hard error. Will a compiler optimize it to a load of a constant value? Very likely. Compilers are good at that sort of thing.

Solution 2:

I think it is better to use consteval function, but if you cannot change it, you can simply use a temporary variable which will surely optimize later:

constexpr int func( int i )
{
    return i+2;
}

int main()
{
     constexpr int i1 = func(8);
     auto i2 = i1;
     i2 = 9;
}

Although you may not like this method, I think it works without any problem....

You can also use something like this(Based on StoryTeller idea):

template<typename T> constexpr std::remove_const_t<T> const_eval(T&& res) { return res; }

which support returning references from method too.