C++中函数调用的方式

一,为什么C++的要有不同的函数调用方式
C++采用参数压栈的方式来进行函数调用:
  1. 调用者依次把参数压栈,然后调用函数。
  2. 函数被调用以后,在堆栈中取得数据,并进行计算。
  3. 函数计算结束以后,或者调用者、或者函数本身修改堆栈,使堆栈恢复原装。

因此,有这几个问题需要明确:

  1. 函数调用时参数需要以什么样的方式进行传递。对于不同的函数调用,参数的传递方式应该采取不同的方式对待,以使得其调用的效率尽可能得高。
  2. 调用结束时系统堆栈要由谁来清除。不同的编译器产生栈的方式不尽相同,那么调用者能否正常的完成清除工作呢?答案是不能。

    由此,C++的函数调用方式一共分五种:
    stdcall ,cdecl ,fastcall ,thiscall ,naked call

    二,C++几种主要的函数传递方式:


    2.1 __stdcall

    __stdcall是C++最常用的参数调用方式了。也许你认为你见得还不够多,那么请看下列头文件:

    其实我们通常看到的WINAPI,CALLBACK,APIENTRY 都是__stdcall的调用方式。
    __stdcall调用方式具有如下特点:


    __stdcall的调用方式的优点是函数自己清栈。这样上面的问题就解决了,调用方不需要帮助函数清理堆栈,调用就方便多了。在跨平台的开发或者调用中,都采用__stdcall。
    2.2 _cdecl
    虽然__stdcall非常强大,但是依然有它无法处理的特例。典型的,就是printf()函数。
    printf是个不定长参数的函数,因此函数方无法知道参数的长度,只有调用方知道,因此函数方面无法完成堆栈的清理工作。
    _cdecl调用方式具有如下特点:

    • 参数从右向左压栈(和__stdcall一样)。
    • 系统堆栈的清理是由调用方来完成的。
    • 翻译的方式是函数名前自动加前导的下划线,沿用上面的例子,该函数如果为_cdecl的,将被翻译成_func。
    • 2.3 _fastcall
      这种调用方式和它的名称一样,比较快,因为它优先使用寄存器进行函数的参数调用。它的调用规则如下:

    • 函数的第一个和第二个DWORD参数(或者尺寸更小的)通过ecx和edx传递,其他参数通过从右向左的顺序压栈。
    • 系统堆栈由被调用方进行清理。
    • 翻译方式类似__stdcall.
    • 2.4 _thiscall
      这种调用方式是用在类成员函数的调用的。它的特点是:

    • 参数从右向左压栈。
    • 如果参数是固定长的话,则函数自身清理堆栈(__stdcall),否则,则由调用方清理堆栈(类似_cdcel)
    • 翻译方式取决参数是否定长。 2.5 naked call
      这种调用方式比较少,不介绍。

      参考资料:
      http://blog.csdn.net/fly2k5/archive/2005/12/05/544112.aspx
    • 0
      点赞
    • 5
      收藏
      觉得还不错? 一键收藏
    • 0
      评论

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值