gcc为什么自己实现printf还静态链接libc不会报符号重复定义?

看下面这个例子:


image.png

为什么libc.a中已有printf定义,自己又定义了一个printf,却没有报符号重定义错误?
下面用一个小工程解释这个问题。
工程中有三个源文件,a.c、b.c、main.c。a.c和b.c生成静态库libsub.a,main.c生成应用并链接libsub.a。
头文件common.h中的内容如下:

#ifndef COMMON_H_
#define COMMON_H_

void funa1(void);
void funa2(void);
void funb(void);

#endif

源文件a.c中的内容如下:

#include "common.h"

void funa1(void)
{
}

void funa2(void)
{
}

源文件b.c中的内容如下:

#include "common.h"

void funb(void)
{
}

CMakeLists.txt中的内容如下:

cmake_minimum_required(VERSION 3.15)
project(main C CXX)

add_library(sub STATIC a.c b.c)
add_executable(main main.c)
target_link_libraries(main sub)

main调用funb

image.png

生成的应用中只有符号funb,而没有funa1和funa2

main调用funa1

image.png

生成的应用中有符号funa1和funa2,而没有funb。

从以上两个例子中可以得到一个结论:应用链接静态库时,是以object为单位来链接的。应用用到哪个函数,就会把定义了这个函数的object中的所有函数都链接进来。没有用到的object不会链。

main实现funb,并调用funb

image.png

main实现funa1,并调用funa1

image.png

从以上两个例子中可以得到一个结论,应用只有未解析的符号才会去库里找。如果符号能解析,就不会再去库里找这个符号了。上面两个图中的funb和funa1都是main中自己定义的函数。

main实现funa1,并调用funa2

image.png

出现符号重定义错误了。因为main中没有定义funa2,要去libsub.a中找,把a.c中所有函数都链了进来,出现了两个funa1的定义。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容