关于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
在这种情况下,所有成员函数都被编译为非内联的。

关于extern和inline的用法

extern 用白话文来讲,就是此处我需要用到函数或者变量,我在其他地方已经声明了,在哪声明的?你只管用就行,不需要知道在哪声明的。 举个...
  • cjh965063777
  • cjh965063777
  • 2016年07月27日 16:18
  • 999

小问题大思考之C++里的inline函数

inline,一个神奇的关键字。有了它,函数,你同时就可以获取函数和宏的优点。inline定义的函数,比起没有inline的函数来说,没有执行函数调用所带来的负担(对此可参见《C++程序的内存布局》)...
  • imyfriend
  • imyfriend
  • 2013年10月13日 11:51
  • 7991

C++中的inline关键字

在c/c++中,为了解决一些频繁调用的小函数大量消耗栈空间(栈内存)的问题,特别的引入了inline修饰符,表示为内联函数。 内联函数的引入有利有弊,使用时应当注意。...
  • kaige2111
  • kaige2111
  • 2016年04月29日 11:12
  • 5961

gcc 编译器对 inline 函数的支持

C99版的C语言引入了inline关键字开始支持inline 函数,在这之前传统的C语言(C89)是没有inline 关键字的,也不支持inline 函数。不过大多数 C89 的编译器都将inline...
  • liyuanbhu
  • liyuanbhu
  • 2015年01月06日 22:25
  • 5361

java 代码细节(Inline Method)

这个观点来自《重构-----改善既有代码的设计》 A method’s body is just as clear as its name. 02 Put the method’...
  • jianguo_liao19840726
  • jianguo_liao19840726
  • 2013年06月11日 21:59
  • 901

C++inline函数简介

1.inline函数简介 inline函数是由inline关键字来定义,引入inline函数的主要原因是用它替代C中复杂易错不易维护的宏函数。 2.编译器对inline函数的处理办法 inl...
  • K346K346
  • K346K346
  • 2016年07月31日 22:39
  • 4019

关于inline 函数的总结

关于一天一总结: 1.关于C++inline 关键字,以下说法正确的是:D A 使用inline  关键字的函数会被编译其器在调用处展开 B  头文件中可以包含inline函数的声明 C.可以...
  • chenjieyujiayou
  • chenjieyujiayou
  • 2017年05月17日 17:17
  • 302

内联(inline)函数的优缺点

最近在看LinuxKernel Development,这本书主要是讲了Linux内核的概念,对于整体的框架有了一个描述,这里记录下看到的一些有用的东西,便于以后整理。     Inline这个名称...
  • j00362
  • j00362
  • 2015年12月01日 09:23
  • 1684

类成员声明与定义前加inline的区别(C++ inline 函数)

转载自:http://www.cnblogs.com/berry/articles/1582702.html 参考:http://msdn.microsoft.com/zh-cn/library/wi...
  • fengzizhuang
  • fengzizhuang
  • 2014年03月18日 20:34
  • 2557

GCC和C99标准中的inline

本文介绍了GCC和C99标准中inline使用上的不同之处。inline属性在使用的时候,要注意以下两点: inline关键字在GCC参考文档中仅有对其使用在函数定义(Definit...
  • Decisiveness
  • Decisiveness
  • 2015年03月09日 17:41
  • 991
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于inline
举报原因:
原因补充:

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