versiones dev compiler c++ c++11

c++ - dev - ¿Por qué los espacios de nombres anónimos no son un reemplazo suficiente para el espacio de nombres estático, según el comité de estándares?



c++17 (3)

Según esta respuesta , las variables estáticas con ámbito de espacio de nombres no se detectaron en C ++ 11. Es decir, quedaron obsoletos en C ++ 03, porque los espacios de nombres anónimos se consideraron mejores. Pero C ++ 11 los dejó de lado.

¿Por qué? N3296 enumera el razonamiento para esto como:

El uso de estática en el ámbito del espacio de nombres no debe ser desaprobado. Los espacios de nombres anónimos no son un reemplazo suficiente para la funcionalidad.

Esto fue aparentemente aceptado por el comité. ¿Por qué? ¿Qué pasa con los espacios de nombres anónimos que no reemplazan completamente esta funcionalidad?

Preferiría las respuestas que tenían alguna documentación o documento de una discusión del comité de estándares.


Con los espacios de nombre sin nombre no puede asignar un enlace interno variable dentro del mismo espacio de nombre en el que se encuentra actualmente. Con static , puede. Por ejemplo, el siguiente uso de espacios de nombres sin nombre no proporciona una vinculación interna variable global

namespace { int a; } int a; // oops, no error!

Si el primero a hubiera sido declarado como static , el intento de declarar un segundo en un alcance global habría sido un error inmediato porque el primero ya existe en el ámbito global.

Por lo tanto, para lograr su trabajo de crear una identidad única, los espacios de nombre sin nombre colocan a las entidades en diferentes espacios de nombres (además de afectar su vinculación). static solo afecta el enlace, dejando el espacio de nombre de las funciones y variables que son miembros sin cambios.


La respuesta del usuario en las trincheras sería que los nombres en espacios de nombres no nombrados (el término del estándar para espacios de nombres anónimos) tienen enlaces externos y los nombres declarados static en el nivel de espacio de nombres tienen enlaces internos .

La vinculación interna tiene dos ventajas, y solo uno de los espacios de nombres sin nombre también lo proporciona:

  1. Hacen nombres locales a la unidad de traducción. Puedo definir la misma función de manera diferente en diferentes unidades de traducción sin violar la regla de una sola definición. Esta propiedad se comparte con nombres en el espacio de nombre sin nombre, adornándolos con un nombre de espacio de nombre único.

  2. Impiden que el nombre entre en la tabla de símbolos global. Esto es estrictamente una optimización, pero importante en la práctica. Esta propiedad no está compartida por nombres en el espacio de nombre sin nombre.

Por lo tanto, en general, un programa que usa funciones static para el nivel de espacio de nombres local de la unidad de traducción genera menos trabajo para el vinculador y puede ejecutarse más rápidamente que el programa equivalente que utiliza el espacio de nombre sin nombre.

Dicho esto, debe usar el espacio de nombre sin nombre para los tipos que desea pasar como argumentos de plantilla, porque los argumentos de la plantilla deben tener un enlace externo.

Así que suelo hacer lo siguiente: defina funciones libres como static , pero coloque tipos en el espacio de nombres sin nombre.


Esta es una explicación más profunda.

Aunque 7.3.1.1 [namespace.unnamed] indica que el uso de la palabra clave estática para declarar variables en el ámbito del espacio de nombres está obsoleto porque el espacio de nombres sin nombre proporciona una alternativa superior, es poco probable que la característica se elimine en cualquier punto en el futuro previsible , especialmente a la luz de las preocupaciones sobre la compatibilidad de C El Comité debería considerar eliminar la depreciación.

Un problema que sé es que los espacios de nombres anónimos no pueden especializar las plantillas fuera del bloque de espacio de nombres. Esta es la razón por la que se introdujo el inline namespace , aunque la static también funciona. Además, la static juega mucho bien con las macros.