Frage

Ich habe diese Situation:

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

und

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

und

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

und

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

Es liegt jedoch kein Linkerfehler vor.Wie sieht der Linker zum Testen aus.cpp der const int param welches ist durch Kern.h im Kern definiert.cpp mit interner Verknüpfung (Standard für konstante Definitionen)?

Wenn ich Kern umschreibe.h wie folgt (zwei Zeilen ändern):

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

es kommt ein Linkerfehler wegen Fehlens param.Und dann, wenn ich es so ändere:

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

alles funktioniert wieder.

Ich dachte, dass es in der ursprünglichen Situation vielleicht ein automatisches Inlining des Klassentests im Kern gibt.cpp, also dieser Test.cpp ist nicht vorhanden und der gesamte Code befindet sich im Kern.cpp, damit alles funktioniert.Aber warum sollte es dann darauf ankommen, die beiden Linien im Kern zu ändern.h?

War es hilfreich?

Lösung

Ihre Annahme über die interne Verknüpfung für konstante Definitionen ist nicht immer wahr.Siehe den Abschnitt Standard 3.5 Program linkage, p.3 (Ich zitiere N3690):

Ein Name mit Namespace-Bereich (3.3.6) hat eine interne Verknüpfung, wenn es der Name von ist

  • eine Variable, Funktion oder Funktionsvorlage, die explizit als statisch deklariert ist;oder,

  • eine nichtflüchtige Variable, die explizit als const oder constexpr deklariert ist und weder explizit als extern noch als zuvor als externe Verknüpfung deklariert;oder

  • ein Datenmitglied einer anonymen Gewerkschaft.

Also für den ersten Fall param hat externe Verknüpfung und alles ist in Ordnung.

Für den zweiten Fall gibt es eine intern verknüpfte param im Kern.cpp, aber es gibt eine andere deklarierte-nur param externe Verknüpfung, aber keine Definition.

Im dritten Fall gibt es einen param wieder.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top