Domanda

Ho questa situazione:

// 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(); }

Tuttavia non è presente alcun errore del linker.In che modo il linker vede per Test.cpp il file const int param che è tramite core.h definito in core.cpp con collegamento interno (impostazione predefinita per le definizioni const)?

Quando riscrivo core.h in questo modo (cambia due righe):

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

si verifica un errore del linker per mancanza param.E poi, quando lo cambio in questo modo:

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

tutto funziona di nuovo.

Ho pensato che forse nella situazione originale c'è un incorporamento automatico della classe Test all'interno di core.cpp, in modo che Test.cpp sia inesistente e l'intero codice sia in core.cpp, quindi tutto funziona.Ma perché dovrebbe dipendere dalla modifica delle due righe in core.h?

È stato utile?

Soluzione

La tua ipotesi sul collegamento interno per le definizioni const non è sempre vera.Vedi la sezione standard 3.5 Program linkage, P.3 (sto citando N3690):

Un nome con ambito namespace (3.3.6) ha un collegamento interno se è il nome di

  • una variabile, funzione o modello di funzione esplicitamente dichiarato statico;O,

  • una variabile non volatile dichiarata esplicitamente const o constexpr e non dichiarata esplicitamente né extern né precedentemente dichiarato di avere un collegamento esterno;O

  • un membro dei dati di un'unione anonima.

Quindi per il primo caso param ha un collegamento esterno e va tutto bene.

Per il secondo caso, esiste un collegamento interno param in core.cpp, ma ce n'è un altro solo dichiarato param con collegamento esterno ma senza definizione.

Nel terzo caso ce n'è uno param Ancora.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top