4.1.11b Subespacio anónimo
§1 La gramática de C++ permite definir subespacios anónimos. Para
esto se utiliza la palabra
namespace sin ningún identificador antes del corchete de apertura:
namespace { // subespacio anónimo
... // Declaraciones }
§2 Todos los subespacios anónimos de ámbito global (no anidados) de la misma unidad de compilación comparten
el mismo espacio de nombres. Es decir, además de los posibles subespacios nominados
existe otro único, de los sin nombre. Ejemplo:
namespace { // subespacio anónimo
int x;
}
namespace ALFA { // subespacio nominado
int x; // esta x es distinta de la anterior
}
namespace { // subespacio anónimo (ampliación del primero)
int y;
int x; // Error: declaración duplicada
}
§3 Todas las variables declaradas en el subespacio anónimo son conocidas en todo el ámbito del fichero, a no
ser que otra definición posterior las oculte [1]. Sin embargo, los subespacios anónimos de las diferentes
unidades de compilación son independientes, y no existe forma de acceder a un
elemento del subespacio anónimo de un fichero desde otro fichero [2]. Considere los
resultados del siguiente ejemplo:
#include <iostream>
using namespace std;
namespace { // subespacio anónimo
int x = 1;
}
namespace ALFA { // subespacio nominado
int y = 10
}
void main (void) { // ====================
{
int x = 2;
cout << "X = " << x << << endl; // Ok.
}
cout << "X = " << x << endl; // Ok.
cout << "Y = " << y << endl; // M.6: Error!!
cout << "Y = " << ALFA::y << endl; // M.7: Ok.
}
En M.7 se obtiene un error: Undefined symbol 'y' in function main
, ya que la variable
y del subespacio
ALFA no es conocida desde el exterior a no ser que se incluya un especificador explícito, como es el caso de la línea M.7.
En cambio, la variable x del subespacio anónimo es automáticamente conocida en el fichero sin necesidad de un especificador
explícito.
Una vez eliminada la sentencia errónea, la salida es:
X = 2
X = 1
Y = 10
La compartimentación antes aludida entre los
miembros de subespacios anónimos de diferentes ficheros,
permite hacer declaraciones
estáticas sin utilizar el especificador static (
4.1.8c), es decir, variables o funciones de ámbito global que solo sean conocidas en el
fichero en que son declaradas.
Ejemplo: supongamos un programa compuesto por dos ficheros fuente: Fuente1.C y Fuente2.C
En el fichero Fuente1.C
#include <iostream>
extern void func(void); // func está definida en Fuente2.C
namespace { // Subespacio anónimo
float pi = 3.14; // pi es conocido solo en este fichero
}
int main() {
float pi = 0.1; // este pi es distinto del anterior
std::cout << "pi = " << pi << std::endl;
func(); // llamada a func (definida en algún sitio)
return 0;
}
En el fichero Fuente2.C
#include <iostream>
namespace { // Subespacio anónimo
float pi = 10.01; // pi es conocido solo en este fichero
void func(void) { // func es conocida solo en este fichero
std::cout << "Versión local de func(): pi = " << pi;
}
}
void func(void) { // puede ser conocida en otros ficheros
std::cout << "Versión global de func(): pi = " << pi;
}
Salida del programa:
pi = 0.1
Versión global de func(): pi = 10.01
[1] Como si al principio del fichero existiera una directiva using ( 4.1.11c) relativa al subespacio anónimo. En el ejemplo anterior es como si el subespacio anónimo se sustituyera por:
namespace ANONIMO {
int x = 1;
}
using ANONIMO;
[2] Precisamente la garantía de esta compartimentación es una de las posibles razones de utilización de subespacios anónimos.