c++ const constexpr magic-numbers

c++ - Matar números mágicos: “const int” vs “constexpr int”(o no hay diferencia al final)



magic-numbers (2)

Digamos que tengo un magic number que quiero deshacerme ...

//whatever.cpp for (int i = 0; i < 42; i++) { //... }

Razonablemente podría matarlo de dos maneras:

O bien con const int SOMETHING_SOMETHING_MEANING_OF_LIFE = 42
o con constexpr int SOMETHING_SOMETHING_MEANING_OF_LIFE = 42
en el archivo fuente .cpp .

¿Hay alguna diferencia significativa entre los dos en este caso (recuerdo que el compilador dedujo que, en cualquier caso, que el valor no cambia y, por lo tanto, el 42 está realmente codificado en el bucle resultante / bucle desenrollado / cualquier código de máquina) o ¿Se reduce a gusto personal?

En un tema relacionado: ¿qué pasaría si el magic number (y, por lo tanto, la cosa que lo reemplaza) se declarara en un archivo de encabezado ( .h ) en lugar de un archivo de origen ( .ccp )? .ccp cambiaría las cosas (y si es así, cómo) ?


¿Hay alguna diferencia significativa entre los dos en este caso (recuerdo que la compilación dedujo que, en cualquier caso, el valor no cambia y en realidad codifica el 42 en el bucle resultante / el bucle desenrollado / cualquier otro código) o se reduce a ¿gusto personal?

No habrá ninguna diferencia en el código en el caso que ha mostrado.

Sin embargo, la diferencia es que una variable constexpr garantiza que el valor se conoce en tiempo de compilación. Ver la respuesta de @ VittorioRomeo.

También es bueno escribir constexpr si es realmente un valor de tiempo de compilación, para fines de documentación: cuando alguien lee su código y ve constexpr , automáticamente sabe que es un valor verdaderamente fijo. Esto es importante en el caso de que la inicialización no sea trivial (por ejemplo, una llamada a una función).

También puede ver constexpr variables constexpr como el verdadero reemplazo de las macros C que contenían literales (por ejemplo, #define FOO 123 ).

Finalmente, recuerda que constexpr implica const .

En un tema relacionado: ¿qué pasaría si el número mágico (y la cosa que lo reemplaza) se declarara en un archivo de encabezado en lugar de un archivo .ccp? ¿Eso cambiaría las cosas?

No. Sin embargo, si está declarando variables globales en un archivo de encabezado, es probable que desee usar inline (disponible en C ++ 17) sobre constexpr , de modo que solo tenga una entidad en el programa, lo que es una ventaja. para evitar problemas de ODR y posiblemente ahorrar memoria y tiempo de inicialización.

Consulte ¿Deben las variables `const` y` constexpr` en los encabezados estar `en línea ''para evitar violaciones de ODR? para más información.


const int puede usarse como parte de una expresión constante solo si se inicializó desde una, pero no le da la garantía de que lo fue.

const int i = 42; // OK, usable in a constant expression int j = 42; const int k = j; // OK, not usable in a constant expression

constexpr int garantiza que el inicializador de su variable es una expresión constante , de lo contrario su programa no se compilará.

constexpr int i = 42; // OK, usable in a constant expression int j = 42; constexpr int k = j; // Compile-time error, ''j'' is not a constant expression

Por lo tanto, si desea asegurarse de que su inicializador sea realmente una expresión constante , constexpr es una mejor opción.