en línea vs constexpr?


Con el nuevo estándar de C++11, ¿cuándo debo usar la palabra clave inline sobre la palabra clave constexpr? ¿La palabra clave constexpr ofrece alguna optimización adicional sobre inline, o simplemente afirma que las cosas deben calcularse en tiempo de compilación?

¿Por qué constexpr funciona en el GCC en algunos casos donde la llamada no es constante, como llamar a foo(x) en una variable no-constexpr? ¿Es esto un error en el GCC o es realmente parte del estándar?

Author: Nicol Bolas, 2011-08-19

3 answers

Afirmar que algo se puede calcular en tiempo de compilación es un tipo de optimización bastante fuerte.

La inserción simplemente elimina una llamada a una función, copiando/pegando el cuerpo de la función en el sitio de la llamada. El cuerpo de la función todavía tiene que ser ejecutado, usted acaba de guardar la sobrecarga de una llamada a la función.

Pero si hace que el mismo código sea evaluado en tiempo de compilación, es libre en tiempo de ejecución.

Pero ni inline ni constexpr son principalmente acerca de optimización. El propósito principal de inline es suprimir la regla de una definición, para que las funciones se puedan definir en encabezados (lo que es útil para las plantillas, y por cierto, también facilita la optimización de inserción)

Y constexpr está ahí porque es útil en la metaprogramación, y por cierto, puede ayudar al compilador a optimizar mejor el código, al mover más cálculos al tiempo de compilación.

 29
Author: jalf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-14 12:48:35

Para citar wikipedia:

C++0x introducirá la palabra clave constexpr, que permite al usuario garantizar que un constructor de función u objeto es un tiempo de compilación constante.

Marque las funciones en línea si son súper cortas. Marque las funciones como constexpr si los resultados son requeridos en tiempo de compilación. (Parámetros de plantilla o tamaños de matriz). Creo que una función puede ser ambas si es necesario.

Se puede llamar a una función o constructor de expresión constante con no constexpr parámetros. Así como un entero constexpr literal puede ser asignado a una variable no-constexpr, también puede una función constexpr ser llamado con parámetros no-constexpr, y los resultados almacenados 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.

Entonces, GCC no es incorrecto en esto.

 2
Author: Mooing Duck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-20 20:19:43

Mientras que inline le 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 objeto", es probable que el compilador inserte el cuerpo de la función en el llamador. constexpr las funciones le dicen al compilador "Esta función no tiene efectos secundarios y no depende de condiciones previas que no sean el parámetro itsself."

constexpr las variables solo dicen " Esta variable no cambia y sus datos se pueden incluir en el código.". Sin embargo, hace un diferencia si se define una variable constexpr en una función estática o no estática, por ejemplo. si un array constexpr no es estático, gcc solo mueve los datos con instrucciones codificadas en la pila mov, mientras que static constexpr solo almacena los datos en la sección .text.

Las expresiones Lambda sin captura asignadas a una variable pueden ser constexpr que no sea con capture, porque sin ellas no necesitan memoria para guardar la captura y funcionan como una clase vacía con operator() sobrecargada (pero incluso pueden ser lanzadas para punteros de función simples con un simple plus unario: +[]{}).

 -2
Author: cmdLP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-08 14:48:08