¿Se asigna memoria a una variable constante estática cuya dirección nunca se usa?

Si nunca uso la dirección de una variable constante estática, ¿se le asigna memoria cuando se utiliza un comstackdor razonablemente moderno?

Depende del tipo de variable y de si “constante” también significa “expresión constante”. Ejemplo:

static const Foo = get_foo(std::cin); static const int q = argc * 3; static const std::string s(gets()); 

Estas variables son constantes, pero necesitan flagrantemente una asignación real.

Por otro lado, la siguiente expresión constante puede que nunca tenga almacenamiento físico:

 static const int N = 1000; static const std::shared_ptr vp(); // constexpr constructor! 

Lo más importante es que las variables miembro constexpr estáticas no necesitan una definición si se tiene cuidado:

 struct Bar { int size() const { return N; } static const int N = 8; }; // does NOT need "const int Bar::N;" 

Existe la posibilidad de que no lo sea, pero eso no importa. No se puede confiar en los detalles de la implementación, solo en el estándar.

En la práctica, el espacio para el almacenamiento estático se puede asignar como parte de la carga binaria inicial, o por el tiempo de ejecución durante el inicio; pero siempre sucederá antes de que se encuentre el código de usuario.

Además de las restricciones que menciona Kerrek SB , el almacenamiento para un valor const expr podría eliminarse si el valor en sí nunca se usa en el tiempo de ejecución.

Esto no necesariamente significa que el valor no debe evaluarse: si una const expr solo se usara como condición de bifurcación, esa condición puede evaluarse estáticamente y otras rutas de código pueden no generarse o pueden ser excluidas por el optimizador.

Casi cualquier almacenamiento con duración static puede eliminarse si la implementación puede garantizar el comportamiento como si el almacenamiento estuviera presente, es decir, una expresión de comparación que se pueda evaluar en el momento de la comstackción, como una const expr diferente, una comparación de puntero en la que se sabe que la rs ser un alias a una variable diferente, o tal vez un tipo incompatible. También se puede eliminar si el valor solo se lee en variables que nunca se leen por sí mismas; o donde el valor puede reducirse a una const expr .

 struct Foo{}; static Foo bar; // static instance Foo* func() { if ( ! (&bar) ) { // always non-NULL // this block may be eliminated Foo* myCopy(new Foo(bar)); return myCopy; } // so 'bar' is never referred to, and we know it has no side- // effects, so the static variable can be eliminated return new Foo(); } 

3.7.1 Duración del almacenamiento estático

2. Si un objeto de duración de almacenamiento estático tiene inicialización o un destructor con efectos secundarios, no se eliminará aunque parezca que no se usa, excepto que un objeto de clase o su copia puede eliminarse como se especifica en 12.8.

La memoria para las variables globales está reservada por el vinculador, no por el comstackdor. Entonces, la pregunta es si el vinculador es lo suficientemente inteligente como para no reservar espacio para las variables globales que solo se utilizan por valor.

Depende del tipo y uso de tales datos; por ejemplo, las constantes de punto flotante generalmente deben cargarse desde la memoria, por lo que deben tener almacenamiento incluso si no usa la dirección directamente.

Dicho esto, la norma sí especifica si puede optimizar el almacenamiento estático (3.7.1.2: [basic.stc.static]):

Si una variable con duración de almacenamiento estático tiene inicialización o un destructor con efectos secundarios, no se eliminará aunque parezca que no se usa, excepto que un objeto de clase o su copia / movimiento se puede eliminar como se especifica en 12.8.

Entonces, si la variable const estática tiene un constructor o destructor, no se puede optimizar (aunque algunos comstackdores / enlazadores lo harán de todos modos). Si no lo hace, puede. Si dependerá del enlazador.