¿Tiene sentido la variable estática constexpr?
Si tengo una variable dentro de una función (digamos, una matriz grande), ¿tiene sentido declararla tanto static
como constexpr
? constexpr
garantiza que la matriz se crea en tiempo de compilación, por lo que el static
sería inútil?
void f() {
static constexpr int x [] = {
// a few thousand elements
};
// do something with the array
}
Es el static
realmente haciendo algo allí en términos de código generado o semántica?
1 answers
La respuesta corta es que no solo es static
útil, es bastante bien siempre va a ser deseado.
Primero, note que static
y constexpr
son completamente independientes el uno del otro. static
define el tiempo de vida del objeto durante la ejecución; constexpr
especifica que el objeto debe estar disponible durante la compilación. La compilación y ejecución son disjuntos y discontiguos, tanto en el tiempo como en el espacio. Así que una vez compilado el programa, constexpr
ya no es relevante.
Cada variable declarado constexpr
es implícitamente const
pero const
y static
son casi ortogonales (excepto por la interacción con static const
enteros.)
El modelo de objetos C++
(§1.9) requiere que todos los objetos que no sean campos de bits ocupen al menos un byte de memoria y tengan direcciones; además, todos estos objetos observables en un programa en un momento dado deben tener direcciones distintas (párrafo 6). Esto no requiere que el compilador cree una nueva matriz en la pila para cada invocación de un función con un array const local no estático, porque el compilador podría refugiarse en el principio as-if
siempre que pueda probar que no se puede observar ningún otro objeto similar.
Eso no va a ser fácil de probar, desafortunadamente, a menos que la función sea trivial (por ejemplo, no llama a ninguna otra función cuyo cuerpo no sea visible dentro de la unidad de traducción) porque los arrays, más o menos por definición, son direcciones. Así que en la mayoría de los casos, la matriz no estática const(expr)
tendrá que ser recreado en la pila en cada invocación, lo que frustra el punto de ser capaz de calcularlo en tiempo de compilación.
Por otro lado, un objeto local static const
es compartido por todos los observadores, y además puede ser inicializado incluso si la función en la que está definido nunca es llamada. Así que nada de lo anterior se aplica, y un compilador no solo es libre de generar una sola instancia de él; es libre de generar una sola instancia de él en el almacenamiento de solo lectura.
Así que definitivamente deberías use static constexpr
en su ejemplo.
Sin embargo, hay un caso en el que no querrías usar static constexpr
. A menos que un objeto constexpr
declarado sea ODR-used o declarado static
, el compilador es libre de no incluirlo en absoluto. Eso es bastante útil, porque permite el uso de arreglos temporales en tiempo de compilación constexpr
sin contaminar el programa compilado con bytes innecesarios. En ese caso, claramente no querrá usar static
, ya que static
es probable que obligue al objeto a existir en ejecución.
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-09-08 11:36:59