constinit în C++

Garantează că o variabilă globală sau statică este inițializată la compilare, dar fără să o facă constantă.

Sintaxă
constinit int contor = 0;
constinit thread_local int x = 5;

Ce face constinit

Variabilele globale și static pot fi inițializate fie la compilare, fie la pornirea programului, prin cod. A doua variantă poate crea o problemă reală: ordinea în care sunt inițializate variabilele globale din fișiere diferite nu este garantată.

constinit cere ca inițializarea să se facă la compilare; dacă nu se poate, programul nu se compilează. Spre deosebire de constexpr, variabila nu devine constantă: o poți modifica normal după aceea.

Se poate folosi doar pentru variabile cu durată statică (globale, static, thread_local), nu pentru variabile locale obișnuite.

Exemple

Exemplul 1: Contor global inițializat la compilare

#include <print>

constinit int vizitatori = 0;

void intra() { ++vizitatori; }

int main() {
    intra();
    intra();
    intra();
    std::println("Vizitatori: {}", vizitatori);
}

Rezultat

Vizitatori: 3

Exemplul 2: Valoare calculată de o funcție constexpr

Inițializarea folosește o funcție constexpr, deci se poate face la compilare. Variabila poate fi apoi modificată, ceea ce nu ar fi fost posibil cu constexpr.

#include <print>

constexpr int capacitate_initiala(int etaje) { return etaje * 20; }

constinit int locuri_parcare = capacitate_initiala(3);

int main() {
    std::println("Locuri la deschidere: {}", locuri_parcare);
    locuri_parcare -= 7;
    std::println("Locuri libere acum: {}", locuri_parcare);
}

Rezultat

Locuri la deschidere: 60
Locuri libere acum: 53

Greșeli frecvente

  • Inițializezi o variabilă constinit cu rezultatul unei funcții obișnuite (care nu e constexpr). Compilatorul refuză: tocmai asta verifică constinit.
  • Crezi că constinit face variabila constantă. Nu o face; dacă vrei și constantă, scrie constexpr (sau constinit const).

Comenzi înrudite

  • constexpr: Cere ca o valoare să fie calculată la compilare; o funcție constexpr poate rula atât la compilare, cât și la rulare.
  • consteval: Definește o funcție imediată: fiecare apel trebuie calculat la compilare, altfel programul nu se compilează.
  • static: Are trei sensuri: variabilă locală care își păstrează valoarea între apeluri, membru comun al clasei sau nume vizibil doar în fișierul curent.
  • thread_local: Fiecare fir de execuție (thread) primește propria copie a variabilei, creată când pornește firul și distrusă la final.