ProgramaciónDesarrollador C++ / de sistemas

Hable sobre las diferencias entre las palabras clave 'mutable', 'volatile' y 'const' en C++. ¿Para qué se utilizan, qué errores típicos ocurren debido a su uso incorrecto?

Supere entrevistas con el asistente de IA Hintsage

Respuesta

const le dice al compilador que la variable es inmutable (no puede ser cambiada después de la inicialización). Se utiliza para declarar variables constantes, así como para métodos que garantizan no modificar el estado del objeto.

mutable permite modificar el valor de un campo de clase incluso dentro de métodos const.

volatile le dice al compilador que el valor de la variable puede cambiar fuera del control del programa (por ejemplo, por hardware), y el compilador no debe optimizar los accesos a ella.

Ejemplo de código

class Logger { public: void log() const { ++count; // Permitido — count se declara mutable } private: mutable int count = 0; }; volatile int flag; void wait() { while (flag == 0) { /* el compilador no optimiza el bucle, ya que flag es volatile */ } }

Pregunta capciosa

«¿Qué sucederá si se declara un miembro de la clase como const y mutable al mismo tiempo?»

Respuesta: No se puede hacer, son calificadores mutuamente excluyentes; el compilador generará un error.


Ejemplos de errores reales debido al desconocimiento de los matices del tema.


Historia

En software industrial para trabajar con hardware, el desarrollador declaró datos, actualizados por interrupciones externas, como enteros normales. La optimización del compilador eliminó lecturas repetidas de estas variables, lo que hizo que el programa "se bloqueara" en un bucle infinito. El problema se diagnosticó solo después de cambiarlos a volatile int.


Historia

Una de las clases de registro tenía un método log() const, donde se requería actualizar el contador de llamadas. Al principio, se hacía a través del puntero const_cast, lo que causó muchas advertencias y errores no evidentes. El problema desapareció después de declarar correctamente el contador como mutable.


Historia

Algunos métodos de la clase se declararon como const, pero los miembros de tipo puntero cambiaban (por ejemplo, para implementar la caché). Esto llevó a violaciones de la lógica de "const-correctness" e incluso UB, si el objeto realmente se ubicaba en una zona de solo lectura. Se debería haber utilizado mutable o cambiado el diseño.