在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 0
?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.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 0
_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 4
?setI@X@@QAEXH@Z ENDP
通过汇编码可以看到,成员函数setI的参数类型在第一次遇见就绑定了类型。
原文链接: https://www.cnblogs.com/chaoguo1234/p/3149017.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/92887
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!