在c++中,一个inline函数实体,在整个class 声明未被完全看到之前,是不会被评估求值的,也就是说,对于类里面内联的成员函数本身的分析,要等到class的声明完全结束之后才开始。
下面试c++源码:

extern int x;//外部声明的x

class X {
public:
float getX() const {
return x;//x绑定的是哪个?
}
private:
float x;//类自身的成员变量x
}; int main() {
X xObj;
float x;
x = xObj.getX();
}

依据上面的规则,内联函数getX绑定的将会是成员变量x(float型)
下面我们只看成员函数getX的汇编码:

?getX@X@@QBEMXZ PROC                    ; X::getX, COMDAT
; _this$ = ecx ; 5 : float getX() const { push ebp
mov ebp, esp
push ecx;压栈到的目的是为了保存对象xObj的首地址(即this指针)预留空间
mov DWORD PTR _this$[ebp], ecx;寄存器ecx中保留xObj对象首地址,存放到刚才分配的空间 ; 6 : return x; mov eax, DWORD PTR _this$[ebp];将对象xObj对象首地址给eax寄存器
fld DWORD PTR [eax];将对象首地址处内存内容写入到浮点数寄存器ST(0)中,作为返回值 也就是将成员变量x的值返回
;可以看到,x确实绑定的是成员变量 ; 7 : } mov esp, ebp
pop ebp
ret
?getX@X@@QBEMXZ ENDP

但是,这种规则对于成员函数的参数却不是这样。
下面是c++源码:

typedef int length;//全局

class X {
public:
void setI(length x) {//length是什么类型?
i = x;
}
private:
typedef float length;//类成员
length i;
}; int main() {
X xObj;
xObj.setI(1.1);
}

下面通过汇编码看成员变量i和成员函数setI的参数x到底是什么类型
下面是mian函数汇编码:

; 13   : int main() {

    push    ebp
mov ebp, esp
push ecx;压栈寄存器ecx的目的,是为了为对象xObj预留4byte空间
;这里没有调用xObj默认构造器是因为编译器没有必要为其提供非无用的默认构造器 ; 14 : X xObj;
; 15 : xObj.setI(1.1); push ;将1压栈作为参数传递(虽然传递的是浮点数1.1,但是这里将参数截取为整型,说明参数length确实为int)
lea ecx, DWORD PTR _xObj$[ebp];将对象xObj的首地址给寄存器ecx,作为隐含参数传递给成员函数setI
call ?setI@X@@QAEXH@Z ; 调用setI ; 16 : } xor eax, eax
mov esp, ebp
pop ebp
ret
_main ENDP

下面是setI函数的汇编码:

?setI@X@@QAEXH@Z PROC                    ; X::setI, COMDAT
; _this$ = ecx ; 5 : void setI(length x) {//length是什么类型? push ebp
mov ebp, esp
push ecx;压栈寄存器ecx是为保留xObj对象的首地址预留空间
mov DWORD PTR _this$[ebp], ecx;寄存器ecx中存放对象xObj首地址,存放到刚才预留的空间 ; 6 : i = x; fild DWORD PTR _x$[ebp];将参数x(int 型)放入浮点数寄存器ST(0)中, 这条指令专门将整型压入浮点寄存器
mov eax, DWORD PTR _this$[ebp];将对象首地址给寄存器eax
fstp DWORD PTR [eax];将浮点数寄存器ST(0)的内容给对象首地址存内存,即给成员变量i赋值(说明i是浮点型) ; 7 : } mov esp, ebp
pop ebp
ret
?setI@X@@QAEXH@Z ENDP

通过汇编码可以看到,成员函数setI的参数类型在第一次遇见就绑定了类型。

从汇编看c++内联函数评估求值的更多相关文章

  1. 嵌入式C语言自我修养 10:内联函数探究

    10.1 属性声明:noinline & always_inline 这一节,接着讲 __atttribute__ 属性声明,__atttribute__ 可以说是 GNU C 最大的特色.我 ...

  2. C++内联函数

    在C语言中,我们使用宏定义函数这种借助编译器的优化技术来减少程序的执行时间,那么在C++中有没有相同的技术或者更好的实现方法呢?答案是有的,那就是内联函数.内联函数作为编译器优化手段的一种技术,在降低 ...

  3. iOS OC内联函数 inline的详解

    inline 在iOS中的一些框架中,static inline是经常出现的关键字组合. static自不用多说,表示在当前文件中应用,如 static A, 在其它文件中也可以出现static A. ...

  4. C++内联函数与宏定义

    用内联取代宏: 1.内联可调试: 2.可进行类型安全检查或自动类型转换: 3.可访问成员变量. 另外,定义在类声明中的成员函数自动转化为内联函数. 文章(一) 内联函数与宏定义 在C中,常用预处理语句 ...

  5. C++内联函数、函数模板之于头文件

    一.基本说明 C++标准中提到,一个编译单元是指一个.cpp文件以及它所include的所有.h文件,.h文件里的代码将会被扩展到包含它的.cpp文件里,然后编译器编译该.cpp文件为一个.obj文件 ...

  6. C++中内联函数

    目录 什么是内联函数 如何使函数内联 为什么要使用内联函数 inline函数的优缺点分析 什么时候该使用内联函数 正文 在C语言中,我们使用宏定义函数这种借助编译器的优化技术来减少程序的执行时间,那么 ...

  7. 【转】ios内联函数 inline

    ios内联函数 inline 缘由 由于在学习使用UIScrollVew开发的过程中,碰到下面这个属性(设置内边距): @property(nonatomic) UIEdgeInsets scroll ...

  8. 【C语言】预处理、宏定义、内联函数 _

    一.由源码到可执行程序的过程 1. 预处理: 源码经过预处理器的预处理变成预处理过的.i中间文件   1 gcc -E test.c -o test.i 2. 编译: 中间文件经过编译器编译形成.s的 ...

  9. 【C语言】预处理、宏定义、内联函数

    一.由源码到可执行程序的过程 1. 预处理: 源码经过预处理器的预处理变成预处理过的.i中间文件 1 gcc -E test.c -o test.i 2. 编译: 中间文件经过编译器编译形成.s的汇编 ...

随机推荐

  1. 通过XSLT转换XML

    Hello,every body.又与大家见面了,哈哈.今天我与大家分享一下XSLT,XSL,XML,XPath.因为项目中有些功能用到了XSLT.XML等技术.所以今天好好研究了一下这几个方面的技术 ...

  2. zoj Grouping(强连通+缩点+关键路径)

    题意: 给你N个人,M条年龄大小的关系,现在打算把这些人分成不同的集合,使得每个集合的任意两个人之间的年龄是不可比的.问你最小的集合数是多少? 分析: 首先,假设有一个环,那么这个环中的任意两个点之间 ...

  3. 在服务器上php执行某些远程函数出错

    Warning: imagecreatefromjpeg(): php_network_getaddresses: getaddrinfo failed: Name or service not kn ...

  4. python笔记之中缀语法和管道实现

    python笔记之中缀语法和管道实现 你知道什么是中缀语法吗?你知道python中的中缀操作是什么吗?那你知道操作python也是可以像unix的管道符一样方便吗?那么,废话不说了,直接上代码. cl ...

  5. JSTL: empty 可以减少很多繁冗的判空(转)

    ${empty student.name }Empty是判空为空返回的真不为空返回的是假 ${(empty student.name)? '空' : '非空'} <c:if test=" ...

  6. PHP中output control

    Output Control 函数可以让你自由控制脚本中数据的输出.它非常地有用,特别是对于:当你想在数据已经输出后,再输出文件头的情况.输出控制函数不对使用 header() 或 setcookie ...

  7. 查看oracle中的中文所占字节数

    select userenv('language') from dual 显示:SIMPLIFIED CHINESE_CHINA.ZHS16GBK 表示一个汉字占用两个字节. 显示:SIMPLIFIE ...

  8. UESTC_温泉旅店 CDOJ 878

    天空飘下一朵一朵的雪花,这是一片纯白的世界. 在天空之下的温泉旅店里,雪菜已醉倒在一旁,冬马与春希看了看说着梦话的雪菜,决定找一点玩的来度过这愉快的晚上. 这家旅店提供一种特色游戏,游戏有n张牌,各写 ...

  9. python刷取CSDN博文访问量之三

    python刷取CSDN博文访问量之三   作者:vpoet 注:这个系列我只贴代码,代码不注释.有兴趣的自己读读就懂了,纯属娱乐,望管理员抬手若有转载一定不要注明来源 #coding=utf-8 i ...

  10. mongodb debug

    1,MongoDb log use local; db.startup_log.find();