C++link如何工作的

本文讲述了C++编译过程中.obj文件的交互性,以及link阶段如何查找和连接符号。重点讲解了链接错误如未解决的外部符号和函数定义/调用一致性问题,提供了解决方案包括使用static、inline和仅声明头文件的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        每个.cpp文件被编译成.obj文件(翻译单元),但是这些文件是不能交互的,这时需要link工作,使各文件结合在一起。

        link的工作:找到每个符号和函数在哪里,并连接起来。每个文件都需要link,因为有main函数。

示例:

        当只编译时,程序没有报错,接下来我们试试link。

        link时(bulid->编译 + link),就会报错显示为main函数的问题

        看错误的开头是LNK的说明是link阶段发生的错误,如果是语法错误实际上错误的开头是C,证明是编译阶段的错误。

错误:未解决的外部符号 unresolved external symbol

错误原因1:link找不到它需要的东西

        当我们把log函数写成logr时,编译不会报错,但是link会报错,因为只有在link阶段会去寻找具体的函数体,而编译阶段只需要声明。

编译成功

 link阶段报错显示无法解析的外部符号Log

但是当注释掉log函数build成功了,因为在这个函数中根本没使用到log函数,link也不会去找它

另一个有趣的现象是,即使在main函数中没有调用Log函数,仅是在函数体中使用Log函数,仍然会报错,原因是即使在这个main函数中你可能会没用到,但是link会认为你在其他cpp文件中可能会用到。

如果你想声明此函数只会在这个文件中生效,则使用static方法,并且你没使用它,则link阶段不会报错。但是一旦你使用了该方法,程序仍然会报错。

当返回值,参数不一致时,link也会报错。

错误原因2:出现了两个相同的东西

因为link不知道该link到那个地方

此时,直接发生编译错误,显示函数已经有主体,因为在同一个文件下,此时还没link。

当改到不同文件下,编译就可以通过。

再看一种不明显的错误:

此时,log函数只被定义了一次,再头文件里,其他两个cpp文件只是调用,link阶段仍然发生了错误,这时问题就出现再头文件上,因为编译器处理头文件仅仅是copy,因此在两个cpp文件里都对Log函数进行了定义。

解决方法一:将头文件的函数定义为static,这样两个cpp文件就有了自己版本的Log函数,对其他文件不可见。

解决方法二:将头文件的函数定义为inline,表示为将调用函数替换为函数体

此时不涉及Log函数的调用

解决方法三:将头文件只改成声明,新建一个cpp文件完成Log函数的定义。

这样在其他文件调用头文件时就不会有Log函数的定义,而link只会指向实现Log函数的cpp文件里

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值