2010-11-15 21 views
14

En C++, poner una función o una variable en un espacio de nombre anónimo hace que su vinculación sea interna, i. mi. lo mismo que declararlo static en un nivel de archivo, pero C++ idiomático.Vinculación de símbolos dentro del espacio de nombres anónimo dentro de un espacio de nombre normal

¿Qué pasa con un espacio de nombres anónimo dentro de un espacio de nombres normal? ¿Todavía garantiza la vinculación interna?

// foo.cpp 

void func1() { 
    // external linkage 
} 

static void func2() { 
    // internal linkage 
} 

namespace { 
    void func3() { 
     // internal linkage 
    } 
} 

namespace ns1 { 
    void func4() { 
     // external linkage 
    } 

    namespace { 
     void func3() { 
      // still internal linkage? 
     } 
    } 
} 
+1

Asunción errónea. Las variables dentro de un espacio de nombre anónimo tienen un enlace externo, a menos que se declare 'estático'. – MSalters

+1

@MSalters: creo que con C++ 11 esto ha cambiado. '§3.5/4: Un espacio de nombres sin nombre o un espacio de nombres declarado directa o indirectamente dentro de un espacio de nombre sin nombre tiene un enlace interno. Todos los demás espacios de nombres tienen enlaces externos. – legends2k

+1

@ legends2k: Eso es parte de otro cambio, que hizo que esos nombres fueran válidos como argumentos de plantilla (En C++ 03, los argumentos de plantilla necesitaban un enlace externo, que las constantes definían en un espacio de nombres anónimo) – MSalters

Respuesta

11

C++ 11 (borrador N3337) §3.5/4: (énfasis)

Un espacio de nombres sin nombre o un espacio de nombres declarado directa o indirectamente dentro de un espacio de nombres sin nombre tiene enlace interno. Todos los demás espacios de nombres tienen enlaces externos. Un nombre que tiene un ámbito de espacio de nombres que no se ha proporcionado con el enlace interno anterior tiene el mismo vínculo que el espacio de nombres adjunto si es el nombre

- una variable; o

- una función; o

- una clase con nombre (cláusula 9), o una clase sin nombre definida en una declaración typedef en la que la clase tiene el nombre typedef para fines de vinculación (7.1.3); o

- una enumeración nombrada (7.2), o una enumeración sin nombre definida en una declaración typedef en la que la enumeración tiene el nombre typedef para fines de vinculación (7.1.3); o

- un enumerador que pertenece a una enumeración con enlace; o

- una plantilla.

Este guarentees que cualquier espacio de nombres sin nombre tiene enlace interno.

¿Qué pasa con un espacio de nombres anónimo dentro de un espacio de nombres normal? ¿Todavía garantiza la vinculación interna?

Aunque dentro de un espacio de nombre nombrado (normal), es un espacio de nombre sin nombre (anónimo) y, por lo tanto, se garantiza que tendrá un enlace interno según el estándar C++ 11.


poniendo una función o una variable en un espacio de nombres en el anonimato hace su enlace interno, i. mi. lo mismo que declararlo estático en un nivel de archivo, pero C++ idiomático.

En C++ 11 el uso de static en este contexto fue undeprecated; aunque unnamed namespace is a superior alternative to static, there're instances where it fails que se remedia por static; inline namespace was introduced in C++11 para abordar esto.

15

No es necesariamente el caso que las entidades en un espacio de nombre anónimo tengan un enlace interno; en realidad pueden tener un enlace externo.

Como el espacio de nombre sin nombre tiene un nombre exclusivo de la unidad de traducción en la que se compiló, no puede hacer referencia a las entidades declaradas desde fuera de esa unidad de traducción, independientemente de su vinculación.

estándar de C++ dice (C++ 03 7.3.1.1/note 82):

Aunque las entidades en un espacio de nombres sin nombre podrían tener vinculación externa, que están calificados de manera efectiva por un nombre único para su unidad de traducción y por lo tanto, nunca se puede ver desde ninguna otra unidad de traducción.

+2

Un seguimiento rápido: ¿Sabes si tener enlaces internos de alguna manera ayuda a un compilador a tomar mejores decisiones de transformación del código para sus optimizaciones, o no es un problema? –

+0

@Alex B: Esa es una buena pregunta. Mi suposición sería que si un compilador o un enlazador pueden realizar optimizaciones en entidades con enlace interno, podrían realizar las mismas optimizaciones en entidades en un espacio de nombres sin nombre. Sin embargo, no puedo decirlo con certeza. Otros aquí sabrían mucho mejor que yo. –

5

$ 3,5/3 - "Un nombre de espacio de nombres que tiene alcance (3.3.6) tiene enlace interno si es el nombre de

- una variable, plantilla de función o función que es declarado explícitamente estática, o bien,

- una variable que se declara explícitamente const y tampoco lo declaró explícitamente externo ni previamente declarado tener conexión externa; o

- un miembro de datos de una unión anónima.

Por lo tanto, dudo que alguno de los nombres 'func3' y 'func4' en su programa tenga un enlace interno. Ellos tienen un enlace externo. Sin embargo, es solo que no pueden derivarse de otras unidades de traducción de acuerdo con la cita de James.

Cuestiones relacionadas