and - constexpr in c++
en lĂnea vs constexpr? (3)
Con el nuevo estándar C ++ 11, ¿cuándo debo usar la palabra clave en inline
sobre la palabra clave constexpr
? ¿ constexpr
palabra clave constexpr
ofrece alguna optimización adicional sobre la inline
o simplemente afirma que las cosas deben computarse en tiempo de compilación?
¿Por qué funciona constexpr
en el GCC en algunos casos donde la llamada no es constante, como llamar a foo(x)
en una variable que no sea constexpr
? ¿Es esto un error en el GCC o es realmente parte del estándar?
Afirmar que algo se puede calcular en tiempo de compilación es un tipo de optimización bastante fuerte.
La incorporación simplemente elimina una llamada de función, copiando / pegando el cuerpo de la función en el sitio de la llamada. El cuerpo de la función aún tiene que ejecutarse, solo se guarda la sobrecarga de una llamada de función.
Pero si hace que el mismo código sea evaluado en tiempo de compilación, es gratis en tiempo de ejecución.
Pero ni inline
ni constexpr
son principalmente sobre optimización. El propósito principal de inline
es suprimir la regla de una definición, de modo que las funciones se puedan definir en los encabezados (lo cual es útil para las plantillas, e incidentalmente, también facilita la optimización de la incorporación)
Y constexpr
está ahí porque es útil en la metaprogramación e, incidentalmente, puede ayudar al compilador a optimizar mejor el código, moviendo más cómputos a tiempo de compilación.
Mientras que inline
dice al compilador "Esta función se usa en algún lugar de esta unidad de traducción y no es pública para otros archivos de objetos", es probable que el compilador inserte el cuerpo de la función en el llamador. constexpr
funciones constexpr
dicen al compilador "Esta función no tiene efectos secundarios y no depende de otras condiciones que no sean el parámetro en sí".
constexpr
variables constexpr
simplemente dicen "Esta variable no cambia y sus datos se pueden incluir en el código". Sin embargo, hace una diferencia si define una variable constexpr en una función estática o no estática, por ejemplo. si una matriz constexpr
no es estática, gcc simplemente mueve los datos con instrucciones mov
codificadas a la pila, mientras que static constexpr
simplemente almacena los datos en la .text
.text.
Las expresiones Lambda sin captura asignadas a una variable pueden ser constexpr distintas a la captura, ya que sin ellas no necesitan memoria para guardar la captura y funcionan como una clase vacía con operator()
sobrecargado operator()
(pero incluso se pueden convertir en punteros de función simple con un simple unico más: +[]{}
).
Para citar wikipedia:
C ++ 0x introducirá la palabra clave constexpr, que le permite al usuario garantizar que una función o un constructor de objetos es una constante de compilación.
Marcar funciones en línea si son super cortas. Mark funciona como constexpr si los resultados se requieren en el momento de la compilación. (Parámetros de la plantilla o tamaños de matriz). Creo que una función puede ser ambas si es necesario.
Se puede llamar a una función de expresión constante o constructor con parámetros no constexpr. Del mismo modo que se puede asignar un entero entero constexpr a una variable que no sea constexpr, también se puede llamar a una función constexpr con parámetros no constexpr, y los resultados se pueden almacenar en variables no constexpr. La palabra clave solo permite la posibilidad de constancia en tiempo de compilación cuando todos los miembros de una expresión son constexpr.
Por lo tanto, GCC no es incorrecto en esto.