在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. hibernate update部分更新

    hibernate update Hibernate 中如果直接使用 Session.update(Object o); 会把这个表中的所有字段更新一遍. 比如: view plaincopy to ...

  2. mysql服务的注册,启动、停止、注销。 [delphi代码实现]

    unit Service; interface uses Windows,Classes,SysUtils,Winsvc,winsock; Type {服务句柄信息} TScmInfo=Record ...

  3. Http响应报文

    HTTP响应也由三个部分组成,分别是:状态行.消息报头.响应正文. 其中,HTTP-Version表示服务器HTTP协议的版本:Status-Code表示服务器发回的响应状态代码:Reason-Phr ...

  4. ###Git 基础图解、分支图解、全面教程、常用命令###

    一.Git 基础图解 转自:http://www.cnblogs.com/yaozhongxiao/p/3811130.html Git 图解剖析 git中文件内容并没有真正存储在索引(.git/in ...

  5. 【剑指offer】面试题20:顺时针打印矩阵

    题目描述 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1     2  3   4 5    6   7   8 9   10 11 12 13 14 15 ...

  6. devStack

    1,devstack shell 脚本开源官网 http://devstack.org/ 脚本功能快速搭建 OpenStack 的运行和开发环境 [Note tips by Ruiy devstack ...

  7. bootstrap之Flick

    Flick package io.appium.android.bootstrap.handler; import com.android.uiautomator.core.UiDevice; imp ...

  8. Android应用程序与SurfaceFlinger服务的关系概述和学习计划

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/7846923 SurfaceFlinger服务负 ...

  9. 淘宝弹性布局方案lib-flexible研究

    1. lib-flexible不能与响应式布局兼容 先说说响应式布局的一些基本认识: 响应式布局的表现是:网页通过css媒介查询判断可视区域的宽度,在不同的范围应用不同的样式,以便在不同尺寸的设备上呈 ...

  10. webpack构建具备版本管理能力的项目

    webpack是时下十分流行的编译和打包工具,它提供一种可扩展的loader的方式,简单的配置,便可以编译打包各类型的文件,包括js.css.image.font.html,以及各种预编译语言都不在话 ...