关于C运行时库的两个问题:sem_post函数的extern与名称映射
关于sem_post()函数的两个问题
问题背景
我想要查看信号量头文件中sem_post()函数的细节,其声明如下:
extern int sem_post (sem_t *__sem) __THROWNL __nonnull ((1));
随后我在glibc源码中找到了sem_post.c文件,但该文件中的函数名为__new_sem_post()。我知道这与CRT相关,但不清楚具体机制,因此有两个问题:
- 为何存在extern关键字,它的作用是什么?
- 函数名如何从
__new_sem_post()变为sem_post()?
问题解答
1. extern关键字的作用
在C语言中,extern的核心作用是声明跨编译单元的符号:
- 头文件里给
sem_post()添加extern,是明确告诉编译器:这个函数的实现代码不在当前头文件,也不在包含该头文件的源文件中,而是存在于其他独立编译的目标文件(比如glibc的库文件)里。 - 这样编译器处理调用
sem_post()的代码时,只会做语法和类型检查,不会去寻找具体实现,留到链接阶段再从指定库中找到对应函数符号完成链接。
2. 函数名的映射机制
glibc中这种函数名转换是通过链接层面的符号别名实现的,核心逻辑如下:
__new_sem_post()是实际承载功能的实现函数,源码中会通过glibc预定义的宏(比如strong_alias)建立别名映射,类似代码如下:strong_alias (__new_sem_post, sem_post)- 这个宏会被编译器翻译成链接器可识别的指令,最终让
sem_post和__new_sem_post指向同一个内存地址的函数实现。 - 这种做法通常是为了兼容旧版本接口、内部函数迭代升级,或者提供多版本函数实现,让外部调用者无需修改代码就能使用最新的函数逻辑。
内容的提问来源于stack exchange,提问作者Ether
相关产品推荐
相关产品推荐

