c++ c++20 constinit

¿Qué es `constinit` en C++ 20?



c++20 (1)

  • ¿Qué significa constinit ? ¿Por qué fue introducido? ¿En qué casos deberíamos usarlo?

Inicializar una variable con una duración de almacenamiento estático puede dar como resultado dos resultados¹:

  1. La variable se inicializa en tiempo de compilación ( constant-initialization );

  2. La variable se inicializa la primera vez que el control pasa por su declaración.

El caso (2) es problemático porque puede conducir al fiasco del orden de inicialización estático , que es una fuente de errores peligrosos relacionados con objetos globales.

La palabra clave constinit solo se puede aplicar a variables con una duración de almacenamiento estático . Si la variable decorada no se inicializa en tiempo de compilación, el programa está mal formado (es decir, no se compila).

El uso de constinit asegura que la variable se inicialice en tiempo de compilación, y que el fiasco del orden de inicialización estático no pueda tener lugar.

  • ¿Hace que una variable sea inmutable? ¿ constexpr const o constexpr ?

No y no.

Sin embargo, constexpr implica constinit .

  • ¿Puede una variable ser const y constinit ? ¿Qué pasa con constexpr y constinit ?

Puede ser tanto const como constinit . No puede ser tanto constexpr como constinit . De la redacción:

Como máximo, una de las palabras clave constexpr , consteval y constinit aparecerá en un decl-specifier-seq.

  • ¿A qué variables se puede aplicar el especificador? ¿Por qué no podemos aplicarlo a variables no static , no thread_local ?

Solo se puede aplicar a variables con una duración de almacenamiento estático o de subprocesos. No tiene sentido aplicarlo a otras variables, ya que constinit tiene que ver con la inicialización estática.

  • ¿Tiene alguna ventaja de rendimiento?

No. Sin embargo, un beneficio colateral de inicializar una variable en tiempo de compilación es que no se necesitan instrucciones para inicializar durante la ejecución del programa. constinit ayuda a los desarrolladores a asegurarse de que sea así sin tener que adivinar o verificar el ensamblaje generado.

¹: Ver https://en.cppreference.com/w/cpp/language/storage_duration#Static_local_variables

constinit es una nueva keyword y specifier en C ++ 20 que se propuso en P1143 .

El siguiente ejemplo se proporciona en el estándar:

const char * g() { return "dynamic initialization"; } constexpr const char * f(bool p) { return p ? "constant initializer" : g(); } constinit const char * c = f(true); // OK constinit const char * d = f(false); // ill-formed

Algunas preguntas me vienen a la mente:

  • ¿Qué significa constinit ? ¿Por qué fue introducido? ¿En qué casos deberíamos usarlo?

  • ¿Hace que una variable sea inmutable? ¿ constexpr const o constexpr ?

  • ¿Puede una variable ser const y constinit ? ¿Qué pasa con constexpr y constinit ?

  • ¿A qué variables se puede aplicar el especificador? ¿Por qué no podemos aplicarlo a variables no static , no thread_local ?

  • ¿Tiene alguna ventaja de rendimiento?

Esta pregunta está destinada a ser utilizada como referencia para las próximas preguntas sobre el constinit en general.