É possível declarar uma ligação estruturada com constinit
especificador começando em C++20?
Por exemplo
struct A { int i, j; };
constinit auto [x, y] = A{ 0, 1 };
Aqui os compiladores divergem um pouco. MSVC reclama:
erro C3694: uma declaração de ligação estruturada não pode conter especificadores diferentes de 'static', 'thread_local', 'auto' e cv-qualifiers
Clang segue com o
erro: a declaração de decomposição não pode ser declarada 'constinit'
Mas o GCC apenas aceita o exemplo. Demonstração online: https://gcc.godbolt.org/z/jaY7ncsPP
Qual implementação está correta aqui?
Por [dcl.constinit]/1 :
Uma declaração de vinculação estruturada não é uma declaração de variável.
Observe também que o mesmo se aplica a
constexpr
também. Poisconstexpr
o GCC também se comporta em linha com os outros compiladores e rejeita a declaração.No entanto, eu me pergunto se essa restrição é intencional por parte dos autores padrão. No momento, não consigo pensar em um motivo.
Conforme mencionado por Jonathan Wakely aqui , não há nenhum problema específico em permitir
constexpr
(e presumivelmente por extensãoconstinit
) uma vinculação estruturada, mas havia questões em aberto quanto à interpretação que atrasou sua adição ao padrão.O trabalho nisso parece estar em andamento aqui . Pelo que posso entender, o objetivo é fazer com que
constexpr
as vinculações estruturadas não apenas sejam impostasconstexpr
na definição de variável implícita, mas também tornar as próprias vinculações estruturadas utilizáveis em expressões constantes, mesmo que a variável tenha duração de armazenamento automática.Entretanto, essa questão mais complexa não é realmente relevante, pois
constinit
deveria ter uma semântica relativamente simples, eu acho, ou seja, para adicionarconstinit
à definição de variável implícita, e deveria ser proibida se essa variável tivesse duração de armazenamento automática, assim como para declarações de variáveis normais.