什么是未定义的引用/未解决的外部符号错误?如何修复它?

什么是未定义的引用/未解决的外部符号错误?常见原因是什么?如何修复/预防

C++程序,按以下步骤进行,如 2.2 (学分为Keith Thompson参考):

翻译语法规则的优先顺序由以下阶段规定[见脚注]

  1. 物理源文件字符以实现定义的方式映射到基本源字符集
    (为行尾指示器引入新行字符)如果
    必要的[剪报]
  2. 删除紧跟在新行字符后面的反斜杠字符(\)的每个实例,将物理源行拼接到
    形成逻辑源行[剪报]
  3. 源文件被分解为预处理标记(2.5)和空格字符序列(包括注释)[剪报]
  4. 执行预处理指令,展开宏调用,并执行_Pragma一元运算符表达式[剪报]
  5. 字符文字或字符串文字中的每个源字符集成员,以及每个转义序列和通用字符名
    在字符文字或非原始字符串文字中,转换为
    执行字符集的对应成员[剪报]
  6. 相邻的字符串文字标记被连接起来
  7. 分隔标记的空白字符不再有效。每个预处理令牌都转换为一个令牌。(2.7). 这个
    对生成的标记进行语法和语义分析并
    翻译成一个翻译单位[剪报]
  8. 翻译单元和实例化单元的组合如下:[SNIP]
  9. 解析所有外部实体引用。库组件链接以满足对中未定义的实体的外部引用
    目前的翻译。所有此类翻译器输出都收集到
    程序映像,其中包含在其
    执行环境。
    (强调矿山)

[footnote]实现的行为必须像这些单独的阶段一样,尽管在实践中不同的阶段可能会折叠在一起

指定的错误发生在编译的最后阶段,通常称为链接。这基本上意味着您将一组实现文件编译成了目标文件或库,现在您想让它们一起工作

假设您在a.cpp中定义了符号a。现在,b.cpp声明了那个符号并使用了它。在链接之前,它只是假设该符号是在某个地方定义的,但它并不关心在哪里。链接阶段负责查找符号并将其正确链接到b.cpp(实际上是链接到使用它的对象或库)

如果您使用的是Microsoft Visual Studio,您将看到项目生成.lib文件。其中包含导出符号表和导入符号表。导入的符号根据链接所针对的库进行解析,导出的符号为使用该.lib(如果有)的库提供

其他编译器/平台也有类似的机制

常见的错误消息有错误LNK2001错误LNK1120错误LNK2019对于Microsoft Visual Studio对于GCC未定义的引用

守则:

结构X
{
虚拟void foo();
};
结构Y:X
{
void foo(){}
};
结构A
{
虚~A()=0;
};
结构B:A
{
虚拟~B(){}
};
外部INTX;
void foo();
int main()
{
x=0;
foo();
Y;
B B;
}

将使用GCC生成以下错误:

/home/AbiSfw/ccvvuHoX.o:在函数“main”中:
prog.cpp:(.text+0x10):对“x”的未定义引用
prog.cpp:(.text+0x19):对“foo()”的未定义引用
prog.cpp:(.text+0x2d):对'A::~A()'的未定义引用
/home/AbiSfw/ccvvuHoX.o:在函数“B::~B()”中:
prog.cpp:(.text._ZN1BD1Ev[B::~B()]+0xb):对“A::~A()”的未定义引用
/home/AbiSfw/ccvvuHoX.o:在函数“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个退出状态

以及Microsoft Visual Studio的类似错误:

1>test2.obj:错误LNK2001:未解析的外部符号“;无效“cdecl foo(无效)”;(?[email protected]@YAXXZ)
1>test2.obj:错误LNK2001:未解析的外部符号“;INTX"(?[email protected]@3HA)
1>test2.obj:错误LNK2001:未解析的外部符号“;public:virtual“thiscall A::~A(void)”;(?1A)@@[email protected])
1>test2.obj:错误LNK2001:未解析的外部符号“;public:virtualvoid“thiscall X::foo(void)”;([email protected]@@UAEXXZ)
1&gt\test2.exe:致命错误LNK1120:4个未解析的外部

常见原因包括:

  • 未能链接到适当的库/对象文件或编译实现文件
  • 已声明和未定义的变量或函数
  • 类类型成员的常见问题
  • 模板实现不可见
  • 符号在C程序中定义,用于C++代码。

  • 跨模块/dll错误地导入/导出方法/类。(MSV特定)
  • 循环库依赖关系
  • 未定义的引用`[email protected]"
  • 相互依存的图书馆秩序
  • 具有相同名称的多个源文件
  • 使用#pragma时键入错误或未包含.lib扩展名(Microsoft Visual Studio)
  • 模板朋友的问题
  • UNICODE定义不一致
  • “失踪”;“外部”;常量变量声明/定义中(仅限C++)

发表评论