Can one declare a structured binding with constinit
specifier starting from C++20?
For example
struct A { int i, j; };
constinit auto [x, y] = A{ 0, 1 };
Here compilers somewhat diverge. MSVC complains:
error C3694: a structured binding declaration can contain no specifiers other than 'static', 'thread_local', 'auto', and cv-qualifiers
Clang follows it with the
error: decomposition declaration cannot be declared 'constinit'
But GCC just accepts the example. Online demo: https://gcc.godbolt.org/z/jaY7ncsPP
Which implementation is correct here?
Per [dcl.constinit]/1:
The constinit specifier shall be applied only to a declaration of a variable with static or thread storage duration.
A structured binding declaration is not a variable declaration.
Also note that the same applies to constexpr
as well. For constexpr
GCC does also behave in line with the other compilers and rejects the declaration.
As mentioned by Jonathan Wakely here, there is no specific problem with allowing constexpr
(and presumably by extension constinit
) on a structured binding, but there were open questions to the interpretation that delayed adding it to the standard.
Work on this seems to be ongoing here. From what I can gather the goal is to make constexpr
structured bindings not only enforce constexpr
on the implicit variable definition, but also to make the structured bindings themselves usable in constant expressions, even if the variable has automatic storage duration.
The latest revisions of that paper also handles constinit
for structured bindings and would make your code well-defined with the expected behavior, i.e. that constinit
will force the implicit variable definition implied by the structured binding declaration to be marked constinit
, so that it must not have dynamic initialization.