`operator new`在链接器层面是如何实现的?
关于
operator new链接器层面实现逻辑的解析 根据C++标准,operator new这类可替换分配函数在每个翻译单元中隐式声明,若程序为任一可替换分配函数提供多个定义,则程序格式错误。简单来说:用户未自定义operator new时,标准库必须提供该函数的实现;用户自定义后,标准库的实现就不能生效。核心的实现逻辑依赖链接器的符号解析规则和标准库的特殊符号标记:
标准库用弱符号标记默认实现
标准库将operator new、operator delete这类可替换函数定义为弱符号(比如GCC/Clang用__attribute__((weak)),MSVC用__declspec(selectany))。弱符号的关键特性是:当链接器遇到同名的强符号(用户自定义的operator new属于强符号,普通全局函数默认都是强符号)时,会直接忽略弱符号,优先使用强符号的定义;如果整个程序中没有该符号的强定义,链接器才会选用标准库提供的弱符号实现。链接器的符号优先级规则
链接器在合并所有目标文件的符号表时,遵循以下逻辑处理同名符号:- 如果存在至少一个强符号定义,所有同名的弱符号都会被丢弃,只保留强符号的实现
- 如果只有弱符号定义,则任选其中一个(这里就是标准库提供的默认实现)
这套规则完美匹配了C++标准的要求:既避免了用户自定义时的重复定义错误,又保证了用户未实现时不会出现符号缺失的问题。
不同平台的具体实现差异
- GCC/Clang生态:标准库的
operator new实现通过编译属性标记为弱符号,用户只需正常定义全局的operator new,链接器就会自动用用户的强符号覆盖标准库的弱符号。 - MSVC平台:通过
__declspec(selectany)标记标准库的默认实现,或者借助链接器的符号解析逻辑,同样实现用户定义优先的效果。
- GCC/Clang生态:标准库的
内容的提问来源于stack exchange,提问作者geometrian
相关产品推荐
相关产品推荐

