g++编译时-lpthread参数位置差异导致pthread_join未定义引用报错
问题根本原因
GCC 链接器对输入项的扫描遵循从左到右的顺序,且默认仅会用后续出现的库文件,来解析前面扫描过程中产生的未定义符号:
- 执行
g++ -lpthread sample.cpp时,链接器先扫描-lpthread,此时还未处理sample.cpp,没有记录到pthread_join这类未定义的多线程相关符号,会直接跳过pthread库的符号加载;后续扫描到sample.cpp产生的未定义符号时,已经没有对应的库提供符号实现,因此抛出引用未定义的错误。 - 执行
g++ sample.cpp -o sample -lpthread时,链接器先扫描sample.cpp,记录下所有未定义的多线程相关符号后,再扫描-lpthread,可以从库中找到对应符号实现,因此链接成功。
解决方案
根据你的编译格式要求,可选择以下任意一种方案:
- 方案1:使用
-pthread编译参数替代-lpthread
这是最推荐的规范写法。-pthread是GCC提供的多线程编译专用参数,会同时开启编译阶段的多线程适配宏定义、链接阶段的pthread库关联,不受链接顺序限制,直接执行g++ -pthread sample.cpp即可正常编译通过,符合绝大多数教学场景的编译格式要求。 - 方案2:强制链接器忽略顺序加载pthread库
如果必须保留-lpthread的写法且需要放在源文件之前,可添加链接器参数关闭按需加载规则,命令如下:
其中g++ -Wl,--no-as-needed -lpthread sample.cpp -Wl,--as-needed-Wl,--no-as-needed会强制链接器加载所有指定库的全量符号,不管当前有没有未定义符号需要依赖,末尾的-Wl,--as-needed用于恢复默认的按需加载规则,避免引入冗余链接。 - 方案3:沟通确认格式规则
库参数放在输入文件末尾是GCC官方推荐的标准写法,你使用的g++ sample.cpp -o sample -lpthread本身符合通用编译规范,可以主动和教授说明链接顺序的限制,确认格式要求是否可以调整。
内容的提问来源于stack exchange,提问作者Jack Nguyen
相关产品推荐
相关产品推荐

