ProgrammazioneSviluppatore di sistemi/C++

Parla delle differenze tra le parole chiave 'mutable', 'volatile' e 'const' in C++. A cosa servono, quali errori tipici si verificano con un loro uso scorretto?

Supera i colloqui con l'assistente IA Hintsage

Risposta

const informa il compilatore che una variabile è immutabile (non può essere modificata dopo l'inizializzazione). Viene utilizzata per dichiarare variabili costanti e anche per metodi che non modificano lo stato dell'oggetto.

mutable consente di modificare il valore di un campo della classe anche all'interno di metodi const.

volatile informa il compilatore che il valore di una variabile potrebbe essere modificato al di fuori del controllo del programma (ad esempio, dall'hardware), e il compilatore non deve ottimizzare gli accessi ad essa.

Esempio di codice

class Logger { public: void log() const { ++count; // Consentito — count è dichiarato mutable } private: mutable int count = 0; }; volatile int flag; void wait() { while (flag == 0) { /* il compilatore non ottimizza il ciclo, poiché flag è volatile */ } }

Domanda trabocchetto

«Cosa succede se dichiari un membro della classe sia come const che mutable

Risposta: Non è possibile farlo, sono qualificatori mutualmente esclusivi; il compilatore genererà un errore.


Esempi di errori reali a causa della mancanza di conoscenza delle sottigliezze dell'argomento.


Storia

Nel software industriale per interagire con l'hardware, un programmatore ha dichiarato dati aggiornati tramite interruzioni esterne come normali int. L'ottimizzazione del compilatore ha rimosso le letture ripetute di queste variabili, causando il "blocco" del programma in un ciclo infinito. Il problema è stato diagnosticato solo dopo averli sostituiti con volatile int.


Storia

Una delle classi di logging aveva un metodo log() const, dove era necessario aggiornare il contatore delle chiamate. Inizialmente, ciò è stato fatto tramite un puntatore const_cast, il che ha causato numerosi avvertimenti e bug non evidenti. Il problema è scomparso dopo la corretta dichiarazione del contatore tramite mutable.


Storia

Alcuni metodi della classe erano dichiarati come const, ma i membri di tipo puntatore venivano modificati (ad esempio, per implementare la caching). Ciò portava a violazioni della logica di "const-correctness" e persino a UB, se l'oggetto veniva effettivamente posizionato in un'area di sola lettura. Era necessario utilizzare mutable o modificare il design.