VS2019编译C代码时LNK2019与C2660报错差异及成因问询
报错差异原因说明
VS生成可执行文件分为编译期和链接期两个核心阶段,两类报错分别出在不同阶段:
第一份代码报LNK2019的原因
- 你提前声明了
void fake(link* p);,调用时传入的参数类型、数量和声明完全匹配,编译期没有发现语法或类型错误,顺利生成了obj文件。 - 进入链接期后,链接器需要找到所有被调用函数的具体实现,你没有定义fake函数,因此抛出「未解析的外部符号」类的LNK2019错误,无法生成最终exe。
第二份代码报C2660而非LNK2019的原因
- VS2019默认对
.cpp后缀的源文件采用C编译规则,C语法中void display();的空参数列表明确表示「该函数不接受任何参数」。 - 你调用时传入了1个int*类型的参数,和声明的参数列表不匹配,编译期直接抛出语法错误C2660,根本不会进入后续的链接阶段,自然不会出现链接类的LNK2019报错。
补充说明:如果将第二份代码改为纯C编译(比如将源文件后缀改为
.c,或在VS中设置编译选项为C),C语法中void display();的空参数列表代表「函数参数信息未指定」,不会判定参数调用错误,编译通过后进入链接期同样会报LNK2019错误。
VS编译流程的对应关系
VS处理源代码的完整流程和报错节点如下:
- 预处理:展开头文件、宏替换,无报错则进入下一步
- 编译:检查语法错误、类型匹配、函数声明与调用的一致性,C开头的错误(比如C2660)都会在这一步中断,不会生成obj文件
- 汇编:将编译后的中间代码转换为机器码,生成对应源文件的obj文件
- 链接:合并所有obj、依赖库,解析外部符号引用,找不到符号定义时抛出LNK开头的错误(比如LNK2019),完成后才会生成exe文件
内容的提问来源于stack exchange,提问作者Tonia James
相关产品推荐
相关产品推荐

