什么是未定义的引用/未解决的外部符号错误?常见原因有哪些?如何解决/预防?
请随意编辑/添加您自己的内容。
最佳答案
编译C++程序的步骤分为2.2个步骤:
翻译语法规则之间的优先顺序由以下阶段指定[见脚注]。
物理源文件字符以实现定义的方式映射到基本源字符集
(为行尾指示符引入新行字符)如果
必要的。[剪]
将删除紧跟新行字符的反斜杠字符(\)的每个实例,将物理源行拼接到
形成逻辑源行。[剪]
源文件被分解为预处理标记(2.5)和空白字符序列(包括注释)。[剪]
执行预处理指令,展开宏调用,并执行_Pragma一元运算符表达式。[剪]
字符文本或字符串文本中的每个源字符集成员,以及每个转义序列和通用字符名
在字符文本或非原始字符串文本中,转换为
执行字符集的相应成员;[SNIP]
相邻的字符串文本标记被连接起来。
分隔标记的空白字符不再有意义。每个预处理标记都转换为一个标记。(2.7节)。这个
从语法和语义上分析产生的标记,并
翻译为翻译单位。[剪]
翻译单元和实例化单元的组合如下:[SNIP]
将解析所有外部实体引用。库组件链接以满足对未在
当前翻译。所有此类转换器输出都收集到
包含执行所需信息的程序映像
执行环境。(强调我的)
[footnote]实现的行为必须像这些独立的阶段一样,尽管实际上不同的阶段可能被折叠在一起。
指定的错误发生在编译的最后阶段,通常称为链接。它基本上意味着你将一堆实现文件编译成对象文件或库,现在你想让它们一起工作。
假设您在a
中定义了符号a.cpp
。现在,b.cpp
声明了这个符号并使用了它。在链接之前,它只是假设符号是在某个地方定义的,但它还不关心在哪里。链接阶段负责找到符号并将其正确链接到b.cpp
(实际上是链接到使用它的对象或库)。
如果您使用的是Microsoft Visual Studio,您将看到项目生成.lib
文件。其中包含一个导出符号表和一个导入符号表。导入的符号将根据链接所针对的库进行解析,导出的符号将提供给使用该符号的库(如果有)。
对于其他编译器/平台也存在类似的机制。
常见的错误消息有Microsoft Visual Studio的.lib
、error LNK2001
、error LNK1120
和GCC的error LNK2019
符号名。
代码:
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;
}
将使用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
以及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
常见原因包括:
(credits to Keith Thompson for the reference)
Failure to link against appropriate libraries/object files or compile implementation files
Declared and undefined variable or function.
Common issues with class-type members
Template implementations not visible.
Symbols were defined in a C program and used in C++ code.
Incorrectly importing/exporting methods/classes across modules/dll. (MSVS specific)
Circular library dependency
undefined reference to `WinMain@16'
Interdependent library order
Multiple source files of the same name
Mistyping or not including the .lib extension when using the
undefined reference to
(Microsoft Visual Studio)Problems with template friends
关于c++ - 什么是 undefined reference / Unresolved external symbol 错误,如何解决?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42770019/