Was sind undefinierte Referenz-/ungelöste externe Symbolfehler? Was sind häufige Ursachen und wie können sie behoben/verhindert werden?
Lösung des Problems
Das Kompilieren eines C++-Programms erfolgt in mehreren Schritten, wie in 2.2 angegeben (Dank an Keith Thompson für die Referenz):
Der Vorrang unter den Syntaxregeln der Übersetzung wird durch die folgenden Phasen festgelegt [siehe Fußnote].
[Fußnote] Implementierungen müssen sich so verhalten, als ob diese getrennten Phasen auftreten, obwohl in der Praxis verschiedene Phasen zusammengefaltet werden können.
Die angegebenen Fehler treten während dieser letzten Phase der Kompilierung auf, die am häufigsten als Verknüpfung bezeichnet wird. Es bedeutet im Grunde, dass Sie eine Reihe von Implementierungsdateien in Objektdateien oder Bibliotheken kompiliert haben und diese nun zusammenarbeiten lassen möchten.
Angenommen, Sie haben das Symbol a
in definiert a.cpp
. Nun, b.cpp
deklarierte dieses Symbol und benutzte es. Vor dem Verknüpfen geht es einfach davon aus, dass dieses Symbol irgendwo definiert wurde, aber es ist noch egal, wo. Die Verknüpfungsphase ist dafür verantwortlich, das Symbol zu finden und es korrekt mit b.cpp
(nun, eigentlich mit dem Objekt oder der Bibliothek, die es verwendet) zu verknüpfen.
Wenn Sie Microsoft Visual Studio verwenden, sehen Sie, dass Projekte .lib
Dateien generieren. Diese enthalten eine Tabelle mit exportierten Symbolen und eine Tabelle mit importierten Symbolen. Die importierten Symbole werden anhand der Bibliotheken aufgelöst, mit denen Sie verknüpfen, und die exportierten Symbole werden für die Bibliotheken bereitgestellt, die diese verwenden .lib
(falls vorhanden).
Ähnliche Mechanismen existieren für andere Compiler/Plattformen.
Häufige Fehlermeldungen sind error LNK2001
, error LNK1120
, error LNK2019
für Microsoft Visual Studio und undefined reference to
symbolName für GCC.
The code:
struct X
{
virtual void foo();
};
struct Y: X
{
void foo() {}
};
struct A
{
virtual ~A() = 0;
};
struct B: A
{
virtual ~B(){}
};
extern int x;
void foo();
int main()
{
x = 0;
foo();
Y y;
B b;
}
generiert die folgenden Fehler mit GCC:
/home/AbiSfw/ccvvuHoX.o: In function `main':
prog.cpp:(.text+0x10): undefined reference to `x'
prog.cpp:(.text+0x19): undefined reference to `foo()'
prog.cpp:(.text+0x2d): undefined reference to `A::~A()'
/home/AbiSfw/ccvvuHoX.o: In function `B::~B()':
prog.cpp:(.text._ZN1BD1Ev[B::~B()]+0xb): undefined reference to `A::~A()'
/home/AbiSfw/ccvvuHoX.o: In function `B::~B()':
prog.cpp:(.text._ZN1BD0Ev[B::~B()]+0x12): undefined reference to `A::~A()'
/home/AbiSfw/ccvvuHoX.o:(.rodata._ZTI1Y[typeinfo for Y]+0x8): undefined reference to `typeinfo for X'
/home/AbiSfw/ccvvuHoX.o:(.rodata._ZTI1B[typeinfo for B]+0x8): undefined reference to `typeinfo for A'
collect2: ld returned 1 exit status
und ähnliche Fehler mit Microsoft Visual Studio:
1>test2.obj: error LNK2001: unresolved external symbol "void __cdecl foo(void)" (?foo@@YAXXZ)
1>test2.obj: error LNK2001: unresolved external symbol "int x" (?x@@3HA)
1>test2.obj: error LNK2001: unresolved external symbol "public: virtual __thiscall A::~A(void)" (??1A@@UAE@XZ)
1>test2.obj: error LNK2001: unresolved external symbol "public: virtual void __thiscall X::foo(void)" (?foo@X@@UAEXXZ)
1>...\test2.exe: fatal error LNK1120: 4 unresolved externals
Häufige Ursachen sind:
- Versäumnis, mit geeigneten Bibliotheken/Objektdateien zu verknüpfen oder Implementierungsdateien zu kompilieren
- Deklarierte und undefinierte Variable oder Funktion.
- Häufige Probleme mit Klassentypmitgliedern
- Vorlagenimplementierungen nicht sichtbar.
- Symbole wurden in einem C-Programm definiert und in C++-Code verwendet.
- Falsches Importieren/Exportieren von Methoden/Klassen über Module/DLLs hinweg. (MSVS-spezifisch)
- Zirkuläre Bibliotheksabhängigkeit
- undefinierter Verweis auf `WinMain@16'
- Interdependente Bibliotheksordnung
- Mehrere Quelldateien mit demselben Namen
- Tippfehler oder Nichteinschließen der.lib-Erweiterung bei Verwendung von
#pragma
(Microsoft Visual Studio) - Probleme mit Vorlagenfreunden
- Widersprüchliche
UNICODE
Definitionen - Fehlendes „extern" in konstanten Variablendeklarationen/-definitionen (nur C++)
Keine Kommentare:
Kommentar veröffentlichen