__stdcall、__cdecl和__fastcall是三种函数调用协议,函数调用协议会影响函数参数的入栈方式、栈内数据的清除方式、编译器函数名的修饰规则等。如下图所示,可以在IDE环境中设定所有函数默认的调用协议,还可以在函数定义时单独设定本函数的调用协议。

  1. 调用协议常用场合
    1. __stdcall:Windows API默认的函数调用协议。
    2. __cdecl:C/C++默认的函数调用协议。
    3. __fastcall:适用于对性能要求较高的场合。
  2. 函数参数入栈方式
    1. __stdcall:函数参数由右向左入栈。
    2. __cdecl:函数参数由右向左入栈。
    3. __fastcall:从左开始不大于4字节的参数放入CPU的ECX和EDX寄存器,其余参数从右向左入栈。
    4. 问题一:__fastcall在寄存器中放入不大于4字节的参数,故性能较高,适用于需要高性能的场合。
  3. 栈内数据清除方式
    1. __stdcall:函数调用结束后由被调用函数清除栈内数据。
    2. __cdecl:函数调用结束后由函数调用者清除栈内数据。
    3. __fastcall:函数调用结束后由被调用函数清除栈内数据。
    4. 问题一:不同编译器设定的栈结构不尽相同,跨开发平台时由函数调用者清除栈内数据不可行。
    5. 问题二:某些函数的参数是可变的,如printf函数,这样的函数只能由函数调用者清除栈内数据。
    6. 问题三:由调用者清除栈内数据时,每次调用都包含清除栈内数据的代码,故可执行文件较大。
  4. C语言编译器函数名称修饰规则
    1. __stdcall:编译后,函数名被修饰为“_functionname@number”。
    2. __cdecl:编译后,函数名被修饰为“_functionname”。
    3. __fastcall:编译后,函数名给修饰为“@functionname@nmuber”。
    4. 注:“functionname”为函数名,“number”为参数字节数。
    5. 注:函数实现和函数定义时如果使用了不同的函数调用协议,则无法实现函数调用。
  5. C++语言编译器函数名称修饰规则
    1. __stdcall:编译后,函数名被修饰为“?functionname@@YG******@Z”。
    2. __cdecl:编译后,函数名被修饰为“?functionname@@YA******@Z”。
    3. __fastcall:编译后,函数名被修饰为“?functionname@@YI******@Z”。
    4. 注:“******”为函数返回值类型和参数类型表。
    5. 注:函数实现和函数定义时如果使用了不同的函数调用协议,则无法实现函数调用。
    6. C语言和C++语言间如果不进行特殊处理,也无法实现函数的互相调用。

原文地址:http://blog.sina.com.cn/s/blog_701526f40100lcy6.html

转载于:https://www.cnblogs.com/mqxs/p/7028440.html

【转】【C++】__stdcall、__cdcel和__fastcall三者的区别相关推荐

  1. C++知识:__stdcall、__cdcel和__fastcall三者的区别

    stdcall.__cdecl和__fastcall是三种函数调用协议,函数调用协议会影响函数参数的入栈方式.栈内数据的清除方式.编译器函数名的修饰规则等. 1.调用协议常用场合 __stdcall: ...

  2. C++知识回顾之__stdcall、__cdcel和__fastcall三者的区别

    __stdcall.__cdecl和__fastcall是三种函数调用协议,函数调用协议会影响函数参数的入栈方式.栈内数据的清除方式.编译器函数名的修饰规则等. 调用协议常用场合 __stdcall: ...

  3. 我先了解一下博客园创建随笔/文章/日记的过程与三者的区别(隐私等级,是否审核等)...

    我先了解一下博客园创建随笔/文章/日记的过程与三者的区别(隐私等级,是否审核等) 转载于:https://www.cnblogs.com/Totooria-Hyperion/p/5260289.htm ...

  4. 学习数据科学、机器学习与AI没有多大交集,一文告诉你三者最大区别

    翻译 | AI科技大本营 参与 | Shawn 编辑 | Donna [AI科技大本营导读]我们常常提及数据科学.机器学习和人工智能,也有一个整体的概念.但是,如果要清晰地说出三者的定义分别是什么,区 ...

  5. C++ 在继承中虚函数、纯虚函数、普通函数,三者的区别

    C++ 在继承中虚函数.纯虚函数.普通函数,三者的区别 1.虚函数(impure virtual) C++的虚函数主要作用是"运行时多态",父类中提供虚函数的实现,为子类提供默认的 ...

  6. 【c++】27.事件驱动、IO复用、sellect、poll、epoll三者的区别

    一.事件驱动的理解: 1.要理解事件驱动和程序,就需要与非事件驱动的程序进行比较.实际上,现代的程序大多是事件驱动的,比如多线程的程序,肯定是事件驱动的.早期则存在许多非事件驱动的程序,这样的程序,在 ...

  7. 转 框架页有Frame、Iframe、Frameset 3个标记,初学者容易将三者混淆,下面分别讲解三者的区别。...

    框架页有Frame.Iframe.Frameset 3个标记,初学者容易将三者混淆,下面分别讲解三者的区别. 10.4.1  Frameset与Frame的区别 首先讲解Frameset与Frame之 ...

  8. Java基础之String,StringBuilder,StringBuffer三者的区别

    Java基础之String,StringBuilder,StringBuffer三者的区别 目录 运行速度方面 线程安全方面 小结 1. 运行速度方面 运行速度,在这方面运行速度快慢为:StringB ...

  9. mysql点击execute_MySQL execute、executeUpdate、executeQuery三者的区别

    execute.executeUpdate.executeQuery三者的区别(及返回值) 一.boolean execute(String sql) 允许执行查询语句.更新语句.DDL语句. 返回值 ...

最新文章

  1. python樱花树画法图片_用Python敲出樱花绽放 | 附代码
  2. oracle解除表锁死1,解除Oracle被锁的表
  3. Ehcache学习一:JDBC caching
  4. 【牛客 - 317B】小a与204(贪心,构造,水题)
  5. failed to allocate 192.19M (201523200 bytes) from device: CUDA_ERROR_OUT_OF_MEMORY: out of memory
  6. MySQL不能启动 Can't start server : Bind on unix socket: Permission denied
  7. CentOS6.8 下MySQL5.6.29主从复制架构配置
  8. 电动执行器平时应该怎么去维护和保养?
  9. javascript的生命周期
  10. MySQL字符集是什么
  11. java hibernate 详解_hibernate详解一
  12. 中国千家主要规划设计勘察单位
  13. 手机照片误删怎么找回
  14. 计算机ppt制作培训心得,PPT课件制作及微课录制心得
  15. linux下使用打印机
  16. dac104s085芯片驱动讲解
  17. iOS开发-常用第三方开源框架介绍(你了解的ios只是冰山一角)--(转)
  18. log夹逼法定位core, 可能存在问题
  19. CoffeeScript入门
  20. matlab中对一个信号加指定信噪比的噪声

热门文章

  1. 网站中人性化提示信息的JavaScript实现
  2. .net 页面传参方式总结
  3. golang用户认证
  4. 数据库经典书籍--SQL必知必会
  5. 怎么优化GO语言服务的内存占用
  6. linux命令netstat
  7. 前端二十七:四彩边框
  8. ICO的“金三角”与区块链的“新大陆”
  9. 构建轻量级的Table View注意事项[UIKit]
  10. iOS8 Size Classes的理解与使用