Pergunta

Eu tenho esta situação:

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

e

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

e

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

e

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

No entanto, não há erro de vinculador.Como o vinculador vê para Test.cpp o const int param que é através de core.h definido em core.cpp com ligação interna (padrão para definições const)?

Quando reescrevo core.h assim (mude duas linhas):

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

ocorre um erro de vinculador por falta param.E então, quando eu mudo assim:

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

tudo funciona novamente.

Pensei que talvez na situação original exista um inlining automático da classe Test dentro de core.cpp, para que Test.cpp seja inexistente e todo o código esteja em core.cpp, para que tudo funcione.Mas por que deveria depender da alteração das duas linhas em core.h?

Foi útil?

Solução

Sua suposição sobre a ligação interna para definições const nem sempre é verdadeira.Veja a seção padrão 3.5 Program linkage, pág.3 (estou citando N3690):

Um nome com escopo de namespace (3.3.6) possui ligação interna se for o nome de

  • uma variável, função ou modelo de função que é explicitamente declarado como estático;ou,

  • uma variável não volátil que é explicitamente declarada const ou constexpr e nem declarada explicitamente extern nem anteriormente declarado ter ligação externa;ou

  • um membro de dados de uma união anônima.

Então, para o primeiro caso param tem ligação externa e está tudo bem.

Para o segundo caso, existe um link interno param em core.cpp, mas há outro somente declarado param tendo ligação externa, mas sem definição.

No terceiro caso, há um param de novo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top