什么是未定义的引用/未解析的外部符号错误,如何解决它? [英] What is an undefined reference/unresolved external symbol error and how do I fix it?
问题描述
什么是未定义的引用/未解析的外部符号错误?什么是常见原因,以及如何修复/防止它们?
随意编辑/添加您自己的 b
产生的令牌在语法和语义上被分析,
被翻译为翻译单元。 [SNIP]
当前翻译中定义的实体的外部引用。所有这样的翻译器输出被收集到
程序映像中,其包含在其
执行环境中执行所需的信息。(强调我)
[footnote] 实施必须表现为发生这些单独的阶段,但实际上不同的阶段可能会折叠在一起。
< blockquote>
指定的错误发生在编译的最后阶段,通常称为链接。它基本上意味着你编译一堆实现文件到目标文件或库,现在你想让他们一起工作。
说你定义的符号 a
。现在, a.cpp
中的 b.cpp
已声明该符号并使用它。在链接之前,它只是假定该符号被定义在某处,但它并不关心在哪里。链接阶段负责找到符号并将其正确链接到 b.cpp
(实际上是使用它的对象或库)。
如果你使用MSVS,你会看到项目生成 .lib
文件。它们包含导出符号表和导入符号表。导入的符号将根据链接的库进行解析,并且为使用 .lib
(如果有)的库提供导出的符号。
其他编译器/平台也有类似的机制。
常见的错误讯息是错误LNK2001 $ c $用于 MSVS 和
的
错误LNK1120
,错误LNK2019
代码:
$ b $
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 产生以下错误: / p>
/home/AbiSfw/ccvvuHoX.o:在main函数中:
prog.cpp :(。 0x10):未定义引用`x'
prog.cpp :(。text + 0x19):未定义引用`foo()`
prog.cpp :(。+ 0x2d):未定义引用`A ::〜A()'
/home/AbiSfw/ccvvuHoX.o:在函数`B ::〜B()'中:
prog.cpp :( .text._ZN1BD1Ev [B: :〜B()] + 0xb):未定义引用`A ::〜A()'
/home/AbiSfw/ccvvuHoX.o:在函数`B ::〜B b prog.cpp :( .text._ZN1BD0Ev [B ::〜B()] + 0x12):未定义引用`A ::〜A()'
/home/AbiSfw/ccvvuHoX.o :(。 rodata._ZTI1Y [typeinfo for Y] + 0x8):未定义引用`typeinfo for X'
/home/AbiSfw/ccvvuHoX.o:(.rodata._ZTI1B[typeinfo for B] + 0x8):未定义引用`typeinfo for A'
collect2:ld返回1退出状态
strong> MSVS :
1> test2.obj:error LNK2001:未解析的外部符号void __cdecl foo )(?foo @@ YAXXZ)
pre>
1> test2.obj:error LNK2001:未解析的外部符号int x(?x @@ 3HA)
1> test2.obj:error LNK2001:unresolved外部符号public:virtual __thiscall A ::〜A(void)(?? 1A @@ UAE @ XZ)
1> test2.obj:error LNK2001:unresolved external symbolpublic:virtual void __thiscall X: :foo(void)(?foo @ X @@ UAEXXZ)
1> ... \test2.exe:致命错误LNK1120:4未解决的外部
常见原因包括:
- 无法链接到适当的库/目标文件或编译实现文件
- 已声明的和未定义的变量或函数。
- 类类型成员的常见问题
- 模板实现不可见。 / a>
- 符号在C程序中定义并在C ++代码中使用。
- 不正确地在模块/ dll中导入/导出方法/类。 (MSVS特定)
- 循环库依赖
- 未定义的引用WinMain @ 16
- 相互依赖的图书馆订单
- 同名的多个源文件
- 使用
#pragma $ c $时Mistyping或不包括.lib扩展名c>(MSVC)
- 模板朋友的问题 < / li>
What are undefined reference/unresolved external symbol errors? What are common causes and how to fix/prevent them?
Feel free to edit/add your own.
Compiling a C++ program takes place in several steps, as specified by 2.2 (credits to Keith Thompson for the reference):
The precedence among the syntax rules of translation is specified by the following phases [see footnote].
- Physical source file characters are mapped, in an implementation-defined manner, to the basic source character set (introducing new-line characters for end-of-line indicators) if necessary. [SNIP]
- Each instance of a backslash character (\) immediately followed by a new-line character is deleted, splicing physical source lines to form logical source lines. [SNIP]
- The source file is decomposed into preprocessing tokens (2.5) and sequences of white-space characters (including comments). [SNIP]
- Preprocessing directives are executed, macro invocations are expanded, and _Pragma unary operator expressions are executed. [SNIP]
- Each source character set member in a character literal or a string literal, as well as each escape sequence and universal-character-name in a character literal or a non-raw string literal, is converted to the corresponding member of the execution character set; [SNIP]
- Adjacent string literal tokens are concatenated.
- White-space characters separating tokens are no longer significant. Each preprocessing token is converted into a token. (2.7). The resulting tokens are syntactically and semantically analyzed and translated as a translation unit. [SNIP]
- Translated translation units and instantiation units are combined as follows: [SNIP]
- All external entity references are resolved. Library components are linked to satisfy external references to entities not defined in the current translation. All such translator output is collected into a program image which contains information needed for execution in its execution environment. (emphasis mine)
[footnote] Implementations must behave as if these separate phases occur, although in practice different phases might be folded together.
The specified errors occur during this last stage of compilation, most commonly referred to as linking. It basically means that you compiled a bunch of implementation files into object files or libraries and now you want to get them to work together.
Say you defined symbol a
in a.cpp
. Now, b.cpp
declared that symbol and used it. Before linking, it simply assumes that that symbol was defined somewhere, but it doesn't yet care where. The linking phase is responsible for finding the symbol and correctly linking it to b.cpp
(well, actually to the object or library that uses it).
If you're using MSVS, you'll see that projects generate .lib
files. These contain a table of exported symbols, and a table of imported symbols. The imported symbols are resolved against the libraries you link against, and the exported symbols are provided for the libraries that use that .lib
(if any).
Similar mechanism exist for other compilers/platforms.
Common error messages are error LNK2001
, error LNK1120
, error LNK2019
for MSVS and undefined reference to symbolName
for 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;
}
would generate the following errors with 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
and similar errors with MSVS:
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
Common causes include:
- 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
#pragma
(MSVC) - Problems with template friends
- Inconsistent
UNICODE
definitions
这篇关于什么是未定义的引用/未解析的外部符号错误,如何解决它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!