C++ inline weak symbol and so on
关于inline这个关键字,听到强调得最多的是,它只是一种对于编译器的建议,而非强制执行的限定。
但事实上,即使这个优化最终由于函数太过复杂的原因没有达成,加上inline关键字(还有在类定义中直接定义的函数也相当于加上了inline关键字)还是会带来一些区别的。
参看C++11标准文档里面的描述:
A function declaration (8.3.5, 9.3, 11.3) with an inline specifier declares an inline function. The inline
specifier indicates to the implementation that inline substitution of the function body at the point of call
is to be preferred to the usual function call mechanism. An implementation is not required to perform this
inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules
for inline functions defined by 7.1.2 shall still be respected.
这里所谓的other rules具体如下:
An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly
the same definition in every case (3.2). [ Note: A call to the inline function may be encountered before its
definition appears in the translation unit. — end note ] If the definition of a function appears in a translation
unit before its first declaration as inline, the program is ill-formed. If a function with external linkage is
declared inline in one translation unit, it shall be declared inline in all translation units in which it appears;
no diagnostic is required. An inline function with external linkage shall have the same address in all
translation units. A static local variable in an extern inline function always refers to the same object.
A string literal in the body of an extern inline function is the same object in different translation units.
[ Note: A string literal appearing in a default argument is not in the body of an inline function merely
because the expression is used in a function call from that inline function. — end note ] A type defined
within the body of an extern inline function is the same type in every translation unit.
这里最关键的就是一个内联的函数,可以在多个cpp文件里面都有定义(回想一下普通函数如果这么干的话会有multiple definition的错误),标准明确了多个cpp文件的定义一定要一致,
但是编译器层面并不检查。
要理解An inline function with external linkage shall have the same address in all translation units. 这句话,可能需要对于链接过程有一定的理解。(深入理解计算机系统(csapp)第7章)。还可以看一下http://blog.copton.net/articles/linker/
这里简单表述就是,C++程序的每一个编译单元(cpp文件),编译完成之后生成一个.o文件,链接过程就是将这些.o文件合成一个可执行文件。
.o文件里是哪些内容呢?很多,关心的主要是以下几项
.text:代码段,包括这个cpp文件里定义的所有函数得到的字节码
.data:全局已初始化数据
.bss:全局未初始化数据
.reltext:引用的外部函数符号(比如我们会在引用外部函数或变量的时候有一个声明)
.reldata引用的外部变量
合成过程需要将各个.o文件的这几个部分聚合到一起:1重定位,聚合之后变量、函数都要重新排布,当然需要重定位2、将.reltext .data节里引用的外部函数,变量等赋予最终重定位之后的地址
看到这里,就能够大概理解,如果两个cpp文件恰好定义了同一个函数,会造成它们生成的.o文件在聚合的时候不知道取哪个定义,那么其它引用这个函数的地方也不知道重定位到哪,
所以会出现multiple definition的错误。而根据上面对于inline内联函数的表述,可以发现,它事实上赋予这种函数一个特别的属性,就是在多个.o文件里都定义了同一个内联函数的时候,
(这里当然不是成功内联的情形,因为那样的话根本只是插入代码段,连函数符号都没有了,更不用担心重定义了),链接器确保只从中选取一个作为最终的符号地址,这样就保证了
不会由重定义的情况出现了。
C++ inline weak symbol and so on的更多相关文章
- GNU的strong symbol和weak symbol
首先,同样的原型的两个函数在连个不同的c文件中都有定义,把这两个c文件编译.连接在一起,也没有什么错误.原因就是因为,gcc中有一个strong symbol和weak symbol的概念.默认函数定 ...
- [原] inline operator delete & DLL boundary
很久以前写在百度空间的这篇文章: [百度空间] [原] 全局operator delete重载到DLL 首先,纠正一个词“重载”,operator new/delete是替换(replacement) ...
- gcc/g++中weak弱符号及alias别名
最近查看linux内核代码时,表现了一些编译器选项如__attribute_((weak)).__attribute__( (alias("target"))),一开始不了解,后来 ...
- C语言之强化,弱化符号weak
一.概述 在C语言中,函数和初始化的全局变量(包括显示初始化为0)是强符号,未初始化的全局变量是弱符号. 对于它们,下列三条规则使用: ① 同名的强符号只能有一个,否则编译器报"重复定义&q ...
- weak alias
Weak Alias 跟 Weak Reference 完全没有任何关系,不过是我在看到 Weak Reference 的时候想到的而已. Weak Alias 是 gcc 扩展里的东西,实际上是函数 ...
- 弱符号__attribute__((weak))
弱符号是什么? 弱符号: 若两个或两个以上全局符号(函数或变量名)名字一样,而其中之一声明为weak symbol(弱符号),则这些全局符号不会引发重定义错误.链接器会忽略弱符号,去使用普通的全局符号 ...
- __attribute__((weak, alias())))
参考gcc的reference: 弱符号: 若两个或两个以上全局符号(函数或变量名)名字一样,而其中之一声明为weak symbol(弱符号),则这些全局符号不会引发重定义错误.链接器会忽略弱符号,去 ...
- 5.24 Declaring Attributes of Functions【转】
转自:https://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html 5.24 Declaring Attributes o ...
- GNU C/C++ __attributes__ GCC中的弱符号与强符号
最近在看一些源代码,遇到了一些使用__attribute__修饰函数和变量的属性方面的代码,不是太了解,很是汗颜,再此做个总结: GCC使用__attribute__关键字来描述函数,变量和数据类 ...
随机推荐
- Jquery 操作Html 控件 CheckBox、Radio、Select 控件 【转】http://www.cnblogs.com/lxblog/archive/2013/01/09/2853056.html
Jquery 操作Html 控件 CheckBox.Radio.Select 控件 在使用 Javascript 编写前台脚本的时候,经常会操作 Html 控件,比如 checkbox.radio ...
- mouseover 和 hover 方法
mouseover 和 hover 方法的不同?jquery hover包括了鼠标移到对象上,同时鼠标再移出对象的过程,相应的子类也被选中. mouseover是鼠标经过对象时,不包含他的子类同时 ...
- easyui datagrid 学习
一.清空datagrid所有数据 //得到所有数据行 var item = $('#ylProductListDataGrid').datagrid('getRows'); if (item) { / ...
- 开源项目导入eclipse的一般步骤[转]
下载到开源项目后,我们还是希望导入到eclipse中还看,这样要方便点,一般的步骤是这样的 打开源代码目录, 如果看到里面有.calsspath .project文件,那么说明这个项目本来就是ec ...
- Octopus系列之重新规范了模板结构,大家快来看啊
模板结构我是这样来设计的:大家请看,下面四个关键字 frontend[前段]backend[后端]member[会员]widget[部件] 前段页面包括 _Frontend_header_1.html ...
- java二维数组的定义
java中的一维数组的定义都熟了,但是二位数组和一维数组的定义有些微差别.在网上看到了篇文章,总结的很详细.转载下了. 原文链接[http://blog.sina.com.cn/s/blog_6189 ...
- Hduacm—5497
#include <cstring> #include <cstdio> #include <iostream> using namespace std; type ...
- 异步加载js
//异步加载js function loadScript(url,callback){ var script = document.createElement("script"); ...
- autoLyout纯代码适配
前言 1 MagicNumber -> autoresizingMask -> autolayout 以上是纯手写代码所经历的关于页面布局的三个时期 在iphone1-iphone3gs时 ...
- Java:String、StringBuffer和StringBuilder的区别
1 String String:字符串常量,字符串长度不可变.Java中String是immutable(不可变)的. String类的包含如下定义: /** The value is used fo ...