c++ - ¿Cuáles son las razones por las que la extensión del espacio de nombres estándar se considera un comportamiento indefinido?
undefined-behavior c++-standard-library (1)
Aquí hay algunas razones:
- Incluso si los nombres en los encabezados deben ser uglificados para evitar interacciones con macros, este requisito no existe para el nombre en los archivos de origen que implementan el código. Si una implementación usa
::std::foo(int)
como parte de su implementación, sería una violación de la regla de una definición. - Se espera que el estándar crezca. Si se pudieran agregar nombres al espacio de nombres estándar, cualquier nombre que se agregue a la biblioteca estándar de C ++ sería un cambio importante. Hasta cierto punto, esto ya es cierto en el sentido de que cualquiera de esos nombres podría ser una macro, pero se considera aceptable romperlos.
- En realidad, no es necesario agregar el espacio de nombres al espacio de nombres
std
: se pueden agregar a otros espacios de nombres arbitrarios, es decir, incluso si las motivaciones dadas anteriormente no son particularmente fuertes, la restricción no se considera importante en ninguna forma. ... y si hay una razón para agregar un nombre al espacio de nombresstd
, claramente afecta el comportamiento.
¿Por qué agregar nombres al std
nombres std
un comportamiento indefinido?
La respuesta obvia es "porque el estándar lo dice", por ejemplo, en C ++ 14 [namespace.std] 17.6.4.2.1 / 1:
El comportamiento de un programa en C ++ no está definido si agrega declaraciones o definiciones al espacio de nombres
std
o a un espacio de nombres dentro del espacio de nombresstd
menos que se especifique lo contrario. ...
Sin embargo, estaría realmente interesado en las razones de esta decisión. Por supuesto, puedo entender que agregar sobrecargas de nombres que ya están en std
podría romper el comportamiento; pero ¿por qué es un problema agregar nombres nuevos, no relacionados?
Los programas ya pueden causar estragos en las macros estándar, por lo que casi todas las implementaciones de bibliotecas estándar deben consistir únicamente en nombres reservados (doble guión bajo y guión bajo seguido de capital) para todas las partes no públicas.
Realmente me interesaría una situación en la que algo como esto puede ser problemático:
namespace std
{
int foo(int i)
{ return i * 42; }
}
#include <algorithm> // or one or more other standard library headers
cuando esto es perfectamente legal y la biblioteca estándar tiene que hacer frente a:
#define foo %%
#include <algorithm> // or one or more other standard library headers
¿Cuál es la razón de este comportamiento indefinido?