内联函数和普通函数的区别只有在两个地方有意义:
1 考试
2 编译器
因为到底内联不内联,如何内联,都是编译器说了算。
请看如下一段代码:
int func1()
{
DWORD ct = ::GetTickCount();
if( 0 == (ct % 2) )
return 0;
else
return 1;
}
__forceinline int func2()
{
DWORD ct = ::GetTickCount();
if( 0 == (ct % 2) )
return 0;
else
return 1;
}
int _tmain(int argc, _TCHAR* argv[])
{
int a = func1();
int b = func2();
cout << a + b << endl;
return 0;
}
在Debug时,即使func2被申明为最严格的__forceinline,他也不会内联,反汇编代码为:
;int a = func1();
call func1 (0F81168h)
mov dword ptr [a],eax
;int b = func2();
call func2 (0F81163h)
mov dword ptr [b],eax
可见func2 并未进入main函数内部。在Release的时候:
;int a = func1();
mov edi,dword ptr [__imp__GetTickCount@0 (0CB2000h)] ;将GetTickCount函数的地址放入EDI
call edi ;调用GetTickCount
movzx esi,al ;调用结果在EAX中,将EAX地位存在在ESI中
and esi,1 ; 相当于取余2的操作
;int b = func2();
call edi ;再次调用GetTickCount获取时间
cout << a + b << endl;
mov ecx,dword ptr [__imp_std::endl (0CB2040h)] ;将endl 对象指针放入ECX
movzx eax,al
and eax,1 ;这两句取余2结果
push ecx ;传递参数endl
mov ecx,dword ptr [__imp_std::cout (0CB2038h)] ;读取cout对象
add eax,esi ;完成加法
push eax ;传递参数a + b
call dword ptr [__imp_std::basic_ostream
00CB102E mov ecx,eax
00CB1030 call dword ptr [__imp_std::basic_ostream
可见,两个函数全部被内联了,在func2的内联中,甚至将取余数的操作放在了cout << a + b << endl;中延迟执行。
因此,一般情况下,内联都是编译器说了算,这里情况非常多,你强制它内联,最后结果不一定内联,你不指定内联,他也可能自动内联。
有一种情况,如果你将类在.h文件中申明,一部分在.h中实现,并申明强制内联,这部分函数一般会被内联的。
内联函数相当于在调用那个地方展开他的方法体,而普通函数就不是了