cómo funciona la palabra clave const en c

9 minutos de lectura

avatar de usuario
pardusco

Quiero saber acerca de const internals en c y c++. ¿Cómo impone el compilador la constancia? Puede alguien ayudarme por favor.

  • ¿Está específicamente interesado en C o C ++, porque puede haber una diferencia? Por ejemplo, marcar un método const en C++ no tiene una construcción equivalente en C.

    – Skurmedel

    11 mayo 2010 a las 17:17


  • ¿Puede alguien ayudarme a cómo el compilador crea const? Solo quiero saber las partes internas y no cómo funciona const en C o C++

    – ratoncito

    11 mayo 2010 a las 18:35

  • (incluso obtienes puntos por hacerlo)

    – Adán

    11 de mayo de 2010 a las 21:08

En general const es 100% compilador. Cuando declaras algo const, el compilador impone restricciones sobre lo que le permitirá escribir. No le permitirá asignar a const escalar, asignar a través de una referencia constante o un puntero, o invocar una función no constante de un objeto constante.

No hay garantía de que el compilador organice algún tipo de protección en tiempo de ejecución.

  • Excelente respuesta Para cualquier persona interesada en leer más, sugiero la sección de C++ FQA sobre la corrección constante: yosefk.com/c++fqa/const.html

    – Eli Cortesano

    11 mayo 2010 a las 17:37

  • @Eli, ¿cómo diablos alguien votó un enlace de FQA? Mejor lea las preguntas frecuentes sobre corrección de const: parashift.com/c++-faq-lite/const-correctness.html . Menos diatribas, más sustancia

    – Johannes Schaub – litb

    11 mayo 2010 a las 18:23

  • @Johannes: De hecho, no estoy de acuerdo con las conclusiones subyacentes de la FQA sobre C++ y felizmente uso C++ en mi trabajo diario, pero creo que la FQA puede ser perspicaz y estimulante, y leerlo me ha ayudado a comprender algunos de los problemas que tengo. en la codificación de C ++ mucho mejor que las preguntas frecuentes. Además, el FQA enlaza directamente con las preguntas frecuentes de cada pregunta, por lo que es fácil ver las respuestas originales. Probablemente debería haber agregado un descargo de responsabilidad de que FQA probablemente no sea un buen recurso para los programadores novatos, quienes definitivamente deberían ceñirse a las preguntas frecuentes.

    – Eli Cortesano

    11 mayo 2010 a las 19:38

avatar de usuario
Hormiga

const palabra clave en C y C++ tiene dos significados semánticos diferentes.

(1) Puede declarar la constancia de un objeto

const SomeType t;

En el caso anterior objeto t es un objeto no modificable. El compilador hará todo lo posible para evitar que lo modifique observando las const-corrección reglas (que no son las mismas en C y C++). Las reglas de corrección de constantes se aplican solo conceptualmente, a nivel de lenguaje, lo que significa que hay formas de eludir estas reglas y que también significa que la consistencia de un objeto no se implementará necesariamente a nivel físico. Es decir, no hay garantía de que el objeto finalmente se coloque en la memoria de solo lectura.

Es importante notar que este tipo de constancia es no removible en el sentido de que cualquier intento de modificar el objeto anterior descartando la constancia conduce a un comportamiento indefinido (excluyendo posibles mutable miembros en C++).

(2) Puede declarar la constancia de un ruta de acceso a un objeto

const SomeType *p;

Lo anterior p se declara como un puntero a const. Esto no significa necesariamente que el objeto p apunta es un objeto constante (como se define en el primer tipo de const sobre). Fácilmente podría ser una no constante, en cuyo caso es perfectamente legal eliminar la constancia de la ruta de acceso anterior y modificar el objeto, aunque generalmente no es una buena práctica de programación. En otras palabras, la constancia de una ruta de acceso es potencialmente retirable.

Teniendo en cuenta lo anterior, la siguiente declaración

const int* const* const* const p = 0;

incluye dos tipos diferentes de const: el último const declara la consistencia del objeto p (primera clase), mientras que el resto de const declarar la constancia de varios niveles de ruta de acceso representada por p (segundo tipo).

p.d. como [possibly unrelated] nota al margen, probablemente valga la pena señalar que el término constante tiene significados drásticamente diferentes en C y C++. En C++ constantes son objetos declarados como const. Cª constantes son literales. Objetos declarados como const no son constantes en terminología C.

  • Apenas recuerdo alguna información que leí hace mucho tiempo que hay una diferencia entre C y C++ en el caso de tipos integrales integrados, como en C++, (a diferencia de C) const puede definir una constante de tiempo de compilación y no necesariamente una variable. No recuerdo lo suficiente como para agregar una respuesta independiente perfectamente correcta, pero si tengo razón, tal vez esta información podría agregarse aquí 🙂

    – Maciej Hehl

    11 mayo 2010 a las 17:50

  • @Maciej H: Sí, respondí en stackoverflow.com/questions/2308194/…, pero no quería entrar en ese tema aquí.

    – Ant

    11 mayo 2010 a las 18:35

  • Al tratar de entender declaraciones como const int* const* const* const p = 0; esta “regla” es útil – Básicamente, ‘const’ se aplica a lo que esté a su izquierda inmediata (excepto si no hay nada allí, en cuyo caso se aplica a lo que esté a su derecha inmediata)

    – Lazer

    12 mayo 2010 a las 15:47

  • @Lazer Entonces, esencialmente, eso podría haberse escrito int const *const *const *const p = 0;

    –Mateen Ulhaq

    31 de mayo de 2019 a las 9:35


Además de la inmutabilidad forzada en tiempo de compilación proporcionada por el uso de const palabra clave que otras respuestas a su pregunta ya han mencionado, usarla a veces permite que el compilador coloque dichos datos en el solo lectura sección de un binario y memoria. De acuerdo con la Sección 2.4.2 “Para siempre consten el artículo de Ulrich Drepper Cómo escribir bibliotecas compartidas hacerlo permite potencialmente que los programas (1) usen menos recursos y (2) se inicien más rápido.

Tenga en cuenta que desechar el constLa falta de datos en tales áreas de memoria de solo lectura da como resultado un comportamiento indefinido, como de costumbre.

Cuando el compilador está compilando el código, calcula el tipo de cada expresión para que pueda verificar su tipo y emitir el código correctamente (como una advertencia cuando intenta almacenar un int en un puntero, o convertir correctamente un entero en un doble) . const-ness puede considerarse parte del tipo. Dado que tiene la información de tipo para la expresión, puede comprobar el tipo de la valor (lado izquierdo de la tarea) y lanza un error si tiene ‘const’ en su tipo.

En C, la palabra clave const hará que una variable sea inmutable, lo que significa que no se puede modificar.

Por lo general, esta es una distinción en tiempo de compilación y no tiene ningún efecto sobre la modificación en tiempo de ejecución de una variable. Por ejemplo, una variable const puede modificarse indirectamente utilizando un puntero a la misma dirección de memoria.

En C++, la palabra clave const tiene más de un significado.

Por ejemplo, una función miembro de clase puede ser “const”, lo que significa que no se permite modificar el estado de una instancia de clase.

Como en C, una variable declarada const también se puede modificar indirectamente usando un puntero, pero también usando la palabra clave “mutable” o el operador const_cast<>.

avatar de usuario
ganso nate

En realidad, esto es algo muy complicado en un compilador de optimización. Sin embargo, comienza de manera simple.

Cuando declara una variable con la palabra clave const (simplemente ignoremos los punteros porque pueden ser const o apuntar a const o ambos) el compilador recuerda que ningún código debería cambiar esa variable (casi). Si el compilador ve un código que cambia una variable const, entonces lo considera un error (u ocasionalmente solo digno de una advertencia, pero por simplicidad lo ignoraré). El compilador también asume que ningún código que no pueda ver (en este momento de todos modos {código en otros archivos .c o posiblemente biblioteca o archivos .s o .asm) cambiará la variable const (a menos que sea const volatile en cuyo caso, asumirá que podría cambiar en cualquier momento, pero seguirá impidiendo que su código lo cambie; esto es útil para SFR mapeado en memoria [special function registers] que se utilizan para leer el estado de un dispositivo, pero no se pueden escribir. Recuerde que c y c ++ se usan para el sistema operativo y la programación integrada).

La suposición de que una variable no cambiará bajo algunas o todas las circunstancias permite que las rutinas de optimización del compilador hagan cosas que de otro modo no podrían hacer. Esto significa cosas como colocar el valor literal de una variable en el flujo de instrucciones en lugar de cargar la dirección de la variable y luego cargar el valor de la variable. También puede asumir que si cargó eso si:

extern const int foo; // note that the value isn't visible, so a load is necessary
...
extern int baz(int, int);
...
int bar(int x, int y) {
   int m, n;
   int r = x / foo; // this would require loading the value of foo from RAM
   m = baz(r, y); // the compiler normally has to assume that a function could change a global
   n = m + r + foo; // but since the global foo is const it shouldn't be able to be changed
                    // by the call to baz and does not need to be reloaded
   return n;
}

Un archivo ejecutable (u otro archivo de objeto) puede tener una sección (.rodata) que solo contiene constantes. En muchos casos, el sistema operativo puede obligar a no permitir que un programa escriba en estos datos (o incluso puede estar en ROM en algunos casos). Esta sección también puede contener versiones de variables no constantes que se utilizan para la inicialización, ya que puede tener cualquier constante, no solo constantes declaradas como const.

Entonces, en C const principalmente solo le dice al compilador que te diga que te equivocaste y que estás tratando de cambiar algo que no debería haberse cambiado. Sin embargo, se permite hacer algunas suposiciones basadas en él.

En C++ se vuelve más complicado. No recuerdo todos los detalles, pero sí recuerdo que puede sobrecargar el nombre de una función en función de si el valor que le pasa es constante o no, lo que puede ser útil.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad