c++ - dev - constantes en c
Const antes o const después? (6)
¿Por qué hay dos formas correctas de especificar los datos de
const
y en qué situación preferirías o necesitarías uno sobre el otro si hubiera alguno?
Básicamente, la razón por la que la posición de const
dentro de los especificadores antes de un asterisco no importa es que la gramática C fue definida de esa manera por Kernighan y Ritchie.
La razón por la que definieron la gramática de esta manera era probable que su compilador de C analizara la entrada de izquierda a derecha y terminara de procesar cada token a medida que lo consumía. El consumo del *
token cambia el estado de la declaración actual a un tipo de puntero. Encontrar const
después de *
significa que el calificador const
se aplica a una declaración de puntero; encontrarlo antes de *
significa que el calificador se aplica a los datos apuntados.
Debido a que el significado semántico no cambia si el calificador const
aparece antes o después de los especificadores de tipo, se acepta de cualquier manera.
Un tipo similar de caso surge cuando se declaran punteros a función, donde:
void * function1(void)
declara una función que devuelvevoid *
,void (* function2)(void)
declara un puntero de función a una función que devuelvevoid
.
Una vez más, lo que hay que notar es que la sintaxis del lenguaje es compatible con un analizador de izquierda a derecha.
Para comenzar, probablemente sepa que const
puede usarse para hacer que los datos de un objeto o un puntero no se puedan modificar, o ambos.
const Object* obj; // can''t change data
Object* const obj; // can''t change pointer
const Object* const obj; // can''t change data or pointer
Sin embargo, también puedes usar la sintaxis:
Object const *obj; // same as const Object* obj;
Lo único que parece importar es qué lado del asterisco pone la palabra clave const
. Personalmente prefiero poner const
a la izquierda del tipo para especificar que los datos no son modificables, ya que me parece que se lee mejor en mi mentalidad de izquierda a derecha, pero ¿qué sintaxis fue lo primero?
Más importante aún, ¿por qué hay dos formas correctas de especificar los datos de const
y en qué situación preferirías o necesitarías uno sobre el otro si hubiera alguno?
Editar:
Entonces parece que fue una decisión arbitraria cuando el estándar de cómo los compiladores deberían interpretar las cosas se redactó mucho antes de que yo naciera. Dado que const
se aplica a lo que está a la izquierda de la palabra clave (¿de manera predeterminada?) Supongo que pensaron que no había daño al agregar "accesos directos" para aplicar palabras clave y escribir calificadores de otras maneras al menos hasta que la declaración cambie. al analizar un * o & ...
Este fue el caso en C también, entonces lo estoy asumiendo?
El orden de las palabras clave en una declaración no es todo eso corregido. Hay muchas alternativas al "verdadero orden". Me gusta esto
int long const long unsigned volatile i = 0;
o debería ser
volatile unsigned long long int const i = 0;
??
Existen razones históricas que indican que la izquierda o la derecha son aceptables. Stroustrup había agregado const a C ++ en 1983 , pero no llegó a C hasta C89 / C90.
En C ++ hay una buena razón para usar siempre const a la derecha. Serás consistente en todas partes porque las funciones miembro de const deben declararse de esta manera:
int getInt() const;
La primera regla es usar el formato que requieran los estándares de codificación locales. Después de eso: poner el const
delante lleva a un final de confusión cuando typedefs están involucrados, por ejemplo:
typedef int* IntPtr;
const IntPtr p1; // same as int* const p1;
Si su estándar de codificación permite typedef''s de punteros, entonces realmente debería insistir en poner el const después del tipo. En todos los casos, pero cuando se aplica al tipo, const debe seguir lo que se aplica a, por lo que la coherencia también argumenta a favor de la const después. Pero las pautas locales de codificación prevalecen sobre todas estas; la diferencia normalmente no es lo suficientemente importante como para retroceder y cambiar todo el código existente.
La regla es:
const se aplica a lo que queda de él. Si no hay nada a la izquierda, se aplica a la cosa correcta.
Prefiero usar const a la derecha de la cosa para ser const porque es la forma "original" const se define.
Pero creo que este es un punto de vista muy subjetivo.
Prefiero la segunda sintaxis. Me ayuda a realizar un seguimiento de "qué" es constante leyendo la declaración de tipo de derecha a izquierda:
Object * const obj; // read right-to-left: const pointer to Object
Object const * obj; // read right-to-left: pointer to const Object
Object const * const obj; // read right-to-left: const pointer to const Object