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.