关于inline

原创 2006年06月23日 10:53:00

是不是在类定义中被定义的成员函数会被自动当作是内联函数?或者在定义成员函数时显式地添加inline关键字,该函数就会被定义成内联的呢?
实际上不是!对于编译器来说,内联函数是一种请求,而不是一种保证(C++ Primer(3Ed) P26)。
下面以在VC++7.0下产生的代码为例。
// inline内联函数演示
// InlineDemo.h

#pragma once

#include <iostream>

using namespace std;

class InLine
{
public: 
 // inline?
 InLine() { cout << "InLine Construct!" << endl;}
//  inline?
 void setAB(int a , int b) {this->a = a;this->b = b;}
 int getA();
 int getB();
protected:
 int a , b;
};

// inline?
inline int InLine::getA()
{
 return a;
}

// non-inline?
int InLine::getB()
{
 return b;
}

// InlineDemo.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "InlineDemo.h"

int _tmain(int argc, _TCHAR* argv[])
{
 InLine inlinea;

 inlinea.setAB(10 , 12);

 cout << inlinea.getA() << endl;

 cout << inlinea.getB() << endl;

 return 0;
}

选项/0b1(内联函数展开中的“只适合用于__inline”)打开后的反汇编代码:
.text:004012D0 _main           proc near               ; CODE XREF: j__mainj
.text:004012D0
.text:004012D0 var_58          = dword ptr -58h
.text:004012D0 var_40          = dword ptr -40h
.text:004012D0 var_28          = dword ptr -28h
.text:004012D0 var_C           = dword ptr -0Ch
.text:004012D0 var_8           = dword ptr -8
.text:004012D0
.text:004012D0                 push    ebp
.text:004012D1                 mov     ebp, esp
.text:004012D3                 sub     esp, 58h
.text:004012D6                 push    edi
.text:004012D7                 lea     edi, [ebp+var_58]
.text:004012DA                 mov     ecx, 16h
.text:004012DF                 mov     eax, 0CCCCCCCCh
.text:004012E4                 rep stosd
.text:004012E6                 push    offset
??_C@_0BC@FJCDLOJM@InLine?5Construct?$CB?$AA@ ; "InLine Construct!" 被编译成内联的
.text:004012EB                 push    offset std__cout
.text:004012F0                 call   
j_??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z
.text:004012F5                 add     esp, 8
.text:004012F8                 mov     [ebp+var_28], eax
.text:004012FB                 push    0Ah
.text:004012FD                 mov     ecx, [ebp+var_28]
.text:00401300                 call   
j_?put@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@D@Z ; std::basic_ostream<char,std::char_traits<char>>::put(char)
.text:00401305                 mov     ecx, [ebp+var_28]
.text:00401308                 call   
j_?flush@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@XZ ; std::basic_ostream<char,std::char_traits<char>>::flush(void),自此构造函数输出"InLine Construct!"完成
.text:0040130D                 mov     [ebp+var_C], 0Ah     ;InLine::setAB(10 , 12)开始

.text:00401314                 mov     [ebp+var_8], 0Ch      ;InLine::setAB(10 , 12)结束
.text:0040131B                 mov     eax, [ebp+var_C]
.text:0040131E                 push    eax
.text:0040131F                 mov     ecx, offset std__cout
.text:00401324                 call   
j_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(int)
.text:00401329                 mov     [ebp+var_40], eax    ;InLine::getA()被展开
.text:0040132C                 push    0Ah
.text:0040132E                 mov     ecx, [ebp+var_40]
.text:00401331                 call   
j_?put@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@D@Z ; std::basic_ostream<char,std::char_traits<char>>::put(char)
.text:00401336                 mov     ecx, [ebp+var_40]
.text:00401339                 call   
j_?flush@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@XZ ; std::basic_ostream<char,std::char_traits<char>>::flush(void)
.text:0040133E                 lea     ecx, [ebp+var_C]
.text:00401341                 call   
j_?getB@InLine@@QAEHXZ ; InLine::getB(void)为非内联
.text:00401346                 push    eax
.text:00401347                 mov     ecx, offset std__cout
.text:0040134C                 call   
j_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(int)
.text:00401351                 mov     [ebp+var_58], eax
.text:00401354                 push    0Ah
.text:00401356                 mov     ecx, [ebp+var_58]
.text:00401359                 call   
j_?put@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@D@Z ; std::basic_ostream<char,std::char_traits<char>>::put(char)
.text:0040135E                 mov     ecx, [ebp+var_58]
.text:00401361                 call   
j_?flush@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@XZ ; std::basic_ostream<char,std::char_traits<char>>::flush(void)
.text:00401366                 xor     eax, eax
.text:00401368                 push    edx
.text:00401369                 mov     ecx, ebp
.text:0040136B                 push    eax
.text:0040136C                 lea     edx, dword_401388
.text:00401372                 call    _RTC_CheckStackVars
.text:00401377                 pop     eax
.text:00401378                 pop     edx
.text:00401379                 pop     edi
.text:0040137A                 add     esp, 58h
.text:0040137D                 cmp     ebp, esp
.text:0040137F                 call    _RTC_CheckEsp
.text:00401384                 mov     esp, ebp
.text:00401386                 pop     ebp
.text:00401387                 retn
.text:00401387 _main           endp
在这种情况下,上面两个问题的回答是肯定的。
该选项未未打开是的反汇编代码:
.text:004015D0 _main           proc near               ; CODE XREF: j__mainj
.text:004015D0
.text:004015D0 var_10          = dword ptr -10h
.text:004015D0 var_C           = dword ptr -0Ch
.text:004015D0 var_8           = dword ptr -8
.text:004015D0 var_4           = dword ptr -4
.text:004015D0
.text:004015D0                 push    ebp
.text:004015D1                 mov     ebp, esp
.text:004015D3                 sub     esp, 10h
.text:004015D6                 mov     eax, 0CCCCCCCCh
.text:004015DB                 mov     [ebp+var_10], eax
.text:004015DE                 mov     [ebp+var_C], eax
.text:004015E1                 mov     [ebp+var_8], eax
.text:004015E4                 mov     [ebp+var_4], eax
.text:004015E7                 lea     ecx, [ebp+var_C]
.text:004015EA                 call   
j_??0InLine@@QAE@XZ ; InLine::InLine(void)
.text:004015EF                 push    0Ch
.text:004015F1                 push    0Ah
.text:004015F3                 lea     ecx, [ebp+var_C]
.text:004015F6                 call   
j_?setAB@InLine@@QAEXHH@Z ; InLine::setAB(int,int)
.text:004015FB                 push    offset loc_4010B4
.text:00401600                 lea     ecx, [ebp+var_C]
.text:00401603                 call   
j_?getA@InLine@@QAEHXZ ; InLine::getA(void)
.text:00401608                 push    eax
.text:00401609                 mov     ecx, offset std__cout
.text:0040160E                 call   
j_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(int)
.text:00401613                 mov     ecx, eax
.text:00401615                 call   
j_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(std::basic_ostream<char,std::char_traits<char>> & (*)(std::basic_ostream<char,std::char_traits<char>> &))
.text:0040161A                 push    offset loc_4010B4
.text:0040161F                 lea     ecx, [ebp+var_C]
.text:00401622                 call   
j_?getB@InLine@@QAEHXZ ; InLine::getB(void)
.text:00401627                 push    eax
.text:00401628                 mov     ecx, offset std__cout
.text:0040162D                 call   
j_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(int)
.text:00401632                 mov     ecx, eax
.text:00401634                 call   
j_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(std::basic_ostream<char,std::char_traits<char>> & (*)(std::basic_ostream<char,std::char_traits<char>> &))
.text:00401639                 xor     eax, eax
.text:0040163B                 push    edx
.text:0040163C                 mov     ecx, ebp
.text:0040163E                 push    eax
.text:0040163F                 lea     edx, dword_40165A
.text:00401645                 call    _RTC_CheckStackVars
.text:0040164A                 pop     eax
.text:0040164B                 pop     edx
.text:0040164C                 add     esp, 10h
.text:0040164F                 cmp     ebp, esp
.text:00401651                 call    _RTC_CheckEsp
.text:00401656                 mov     esp, ebp
.text:00401658                 pop     ebp
.text:00401659                 retn
.text:00401659 _main           endp
在这种情况下,所有成员函数都被编译为非内联的。

相关文章推荐

inline assembly code

  • 2014年08月22日 11:20
  • 200KB
  • 下载

Chili 2.2 inline 内联样式增强版

  • 2013年11月08日 14:24
  • 74KB
  • 下载

内联函数(inline)总结

1:定义:       它们看起来象函数,运作起来象函数,比宏(macro)要好得多,使用时还不需要承担函数调用的开销。当内联一个函数时,编译器可以对函数体执行特定环境下的优化工作。这样的优化对"正...

block 和 inline 的区别

  • 2012年09月27日 15:22
  • 33KB
  • 下载

内存注入(IAT Hook 和Inline Hook)

  • 2016年06月02日 20:18
  • 53KB
  • 下载

C++中的内联函数inline总结

突然看到C++Primer中讲到,对于vector的一个循环,调用语句:(示例代码i=v.begin()不是很规范,虽然不会出错,客官请将就着看) for (int i=v.begin() ; i...

inline函数说明(转载)

  • 2008年11月18日 16:18
  • 9KB
  • 下载

学习windows 应用层 inline hook 原理总结

inline hook 实际上就是指 通过改变目标函数头部的代码来使改变后的代码跳转到我们自己设置的一个函数里,产生hook。 今天就拿MessageBoxA这个api函数来做实验。功能就是当程序调...
  • hpp24
  • hpp24
  • 2016年09月12日 10:44
  • 1094

inline hook库

  • 2012年07月30日 17:52
  • 6KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于inline
举报原因:
原因补充:

(最多只允许输入30个字)