O cppreference menciona que se a inicialização contiver uma parte de inicialização dinâmica, o programa ficará malformado ao usar constinit em C++20.
Só me pergunto por que o código a seguir compila então:
constinit std::string str = "Hello";
Como a std::string
classe envolve alocação dinâmica de memória para armazenar caracteres, parece contraditório. Isso não deveria ser proibido devido à parte dinâmica?
Tentei compilar com sinalizadores -std=C++20
e o programa compila bem, o que não deveria acontecer.
Implementações comuns
std::string
não alocam no heap se a string for curta o suficiente (isso é chamado de "otimização de string curta" ou "SSO").Como a quantidade exata de caracteres que podem caber no SSO (se houver) depende da implementação, você provavelmente não deve confiar nela, ou deve pelo menos pesquisar como as três grandes bibliotecas padrão lidam com isso.
Esta resposta é complementar à resposta de @HolyBlackCat.
Conforme explicado lá, o motivo pelo qual você conseguiu compilar:
É devido à otimização de strings curtas (SSO).
Isso é demonstrado nestas 2 demonstrações:
Veja demo1 .
"Hello1234567890123456789012345678901234567890"
neste caso) causa um erro de compilação em todos os 3 compiladores(por exemplo, problemas com o gcc
error: 'constinit' variable 'str' does not have a constant initializer
:).Veja demo2 .
Observe que o comprimento específico suportado pelo SSO depende da implementação.
Na demonstração acima, eu simplesmente aumentei o comprimento até obter a falha. O comprimento máximo para SSO pode mudar em versões futuras.