¿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¹:
-
La variable se inicializa en tiempo de compilación ( constant-initialization );
-
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
oconstexpr
?
No y no.
Sin embargo,
constexpr
implica
constinit
.
- ¿Puede una variable ser
const
yconstinit
? ¿Qué pasa conconstexpr
yconstinit
?
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
yconstinit
aparecerá en un decl-specifier-seq.
- ¿A qué variables se puede aplicar el especificador? ¿Por qué no podemos aplicarlo a variables no
static
, nothread_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
oconstexpr
? -
¿Puede una variable ser
const
yconstinit
? ¿Qué pasa conconstexpr
yconstinit
? -
¿A qué variables se puede aplicar el especificador? ¿Por qué no podemos aplicarlo a variables no
static
, nothread_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.