Pregunta

Tengo esta situación:

// Test.h
extern const int param;
class Test
{
private:
    int i;
public:
    int foo();
};

y

// Test.cpp
#include "Test.h"
int Test::foo() { return param*10; }

y

// core.h
#include "Test.h"
const int param = 1; // should have internal linkage later in core.cpp
int do_stuff ();

y

// core.cpp
#include "core.h"
int do_stuff () { Test obj; return obj.foo(); }
int main() { return do_stuff(); }

Sin embargo, no hay error del vinculador.¿Cómo funciona el enlazador para ver Test.cpp el const int param que es a través del núcleo.h definida en core.cpp tener vinculación interna (opción predeterminada para const definiciones)?

Cuando debo escribir núcleo.h como este (cambiar dos líneas):

// core.h
const int param = 1;
#include "Test.h"
int do_stuff ();

llega un error del vinculador por falta de param.Y luego, cuando lo cambio como este:

// core.h
extern const int param = 1;
#include "Test.h"
int do_stuff ();

todas las obras de nuevo.

Pensé, que tal vez en la situación original existe un sistema automático de alineaciones de la clase de Prueba dentro de core.cpp, por lo que Test.cpp es como que no existe y todo el código está en core.cpp, de modo que todas las obras.Pero ¿por qué debería entonces ser dependiente de cambio de las dos líneas en el núcleo.h?

¿Fue útil?

Solución

Su suposición acerca de la vinculación interna para const definiciones no siempre es cierto.Ver la referencia en la sección 3.5 Program linkage, p.3 (estoy citando N3690):

Un nombre de espacio de nombres de alcance (3.3.6) ha vinculación interna si es el nombre de

  • una variable, función o la función de la plantilla que se declara explícitamente estática;o,

  • un no-volátil variable que se declara explícitamente const o constexpr y ni explícitamente declarado extern ni previamente declarados de vinculación externa;o

  • un miembro de datos de un anónimo de la unión.

Así que para el primer caso param tiene vinculación externa y todo está bien.

Para el segundo caso, hay una interna ligada param en core.cpp pero hay declaró otro-sólo param tener vinculación externa, pero sin definición.

En el tercer caso, hay una param de nuevo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top