什么是未定义的引用/未解决的外部符号错误?常见原因有哪些?如何解决/预防?
请随意编辑/添加您自己的内容。

最佳答案

编译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的.liberror LNK2001error 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/

10-15 02:58
查看更多