ProgrammazioneSviluppatore C++ Embedded

Spiega come funziona la costanza a tempo di collegamento e a tempo di compilazione in C++. Qual è la differenza tra constexpr e const? Quando utilizzare ciascuno di essi?

Supera i colloqui con l'assistente IA Hintsage

Risposta.

In C++ esiste la costanza a tempo di compilazione e a tempo di collegamento.

  • La variabile const è un oggetto che non può essere modificato dopo l'inizializzazione. Ma const non garantisce sempre che il valore sia noto a tempo di compilazione; può essere calcolato solo durante l'esecuzione.
  • constexpr garantisce che l'espressione o la funzione venga calcolata già a tempo di compilazione.

Esempio:

const int x = time(0); // const, ma NON constexpr: il valore viene calcolato durante l'esecuzione constexpr int y = 2 + 2; // constexpr: noto a tempo di compilazione constexpr int square(int x) { return x * x; } int arr[square(3)]; // dimensione dell'array — espressione a tempo di compilazione

Utilizza constexpr per espressioni costanti che devono essere disponibili al compilatore, ad esempio, per le dimensioni degli array o i parametri dei template.

Domanda trabocchetto.

Può una funzione dichiarata come constexpr essere chiamata con argomenti non costanti?

Risposta: Sì! Se gli argomenti sono noti a tempo di compilazione, il risultato verrà calcolato a tempo di compilazione. Se gli argomenti sono noti solo durante l'esecuzione, la funzione verrà calcolata come una normale.

constexpr int double_val(int x) { return x * 2; } int val = std::rand(); int result = double_val(val); // Viene chiamata a tempo di esecuzione

Esempi di errori reali dovuti alla mancanza di conoscenza delle sottigliezze dell'argomento.


Storia

Uno dei moduli impostava la dimensione dell'array tramite const int, pensando che fosse una costante a tempo di compilazione. Su un altro compilatore questo ha causato un errore, perché il valore è stato calcolato a tempo di esecuzione e la dimensione dell'array non corrispondeva allo standard.


Storia

Nel calcolo degli hash, il compilatore non poteva ottimizzare i calcoli perché era usata una variabile const anziché constexpr. Risultato: riduzione delle prestazioni di oltre 2 volte sulle nuove versioni.


Storia

Durante la migrazione ai moderni standard, le parole chiave sono state confuse e la funzione è stata dichiarata come const anziché constexpr, il che ha reso impossibile utilizzare il risultato in espressioni a tempo di compilazione per i template. Una rapida diagnosi ha mostrato l'errore, ma durante la revisione è stata inserita nel master.