__cdecl、__fastcall、__stdcall的区别和各自的意义——MSDN没看明白。

onsky2000 2001-09-07 10:10:39
...全文
235 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
DXD 2001-09-08
  • 打赏
  • 举报
回复
_cdecl、__fastcall、__stdcall是三种调用规范:
调用规范决定从左至右或从右至左的参数传递,有何负责清空堆栈以及函数名称的解释

调用规范 传送顺序 堆栈清除执行者 解释风格
__cdecl 左->右 调用程序 _functionName
__fastcall 右->左 被调用程序 @functionName@nnn
__stdcall 右->左 被调用程序 _functionName@nnn

__fastcall改进了__cdecl的缺省情况,但用在所调用C函数至少有一个参数时,选中该项
编译器将前两个参数送到寄存器ECX DEX,而不是用堆栈,其他参数缺省传入到__cdecl堆栈

__fastcall不许函数使用可变参数长度
__cdecl 由于参数从左压到右,可以使用可变参数长度

__cdecl 优点可变参数

onsky2000 2001-09-07
  • 打赏
  • 举报
回复
多谢指教!谁有心得还可以说的,我想多了解一些。
clack 2001-09-07
  • 打赏
  • 举报
回复
与其他语言编写的程序接口就要用_stdcall,而_cdecl是c语言独有的
liu_feng_fly 2001-09-07
  • 打赏
  • 举报
回复
清理堆栈当然是不需要程序员关心的了,编译器会给你做好这一切的,只是这两种实现的方法有一点差别而已,这个和你自己delete东西是不一样的。
void __fastcall OneFunction(int a,int b)这是告诉编译器,a和b这两个参数要放到寄存器中,这样访问的速度会很快。
看来你是没有用过CALLBACK WINAPI等等这样的函数了,他们就必须是__stdcall的。
onsky2000 2001-09-07
  • 打赏
  • 举报
回复
什么时候必须用其中的一个而不能用另一个呢,假如我这样定义
void __cdecl OneFunction()
{……
}
这能告诉编译器什么呢?我又必须做什么呢?
如果我这样定义
void __fastcall OneFunction()
又如何呢?
onsky2000 2001-09-07
  • 打赏
  • 举报
回复
MSDN文档中有这样一段
The __cdecl calling convention creates larger executables than __stdcall, because it requires each function call to include stack cleanup code
看来倒是要清理堆栈的,不过我们通常不也是清理吗,如char *buff =new char;最后delete buff;干吗还要指明了清理堆栈,我不明白。
liu_feng_fly 2001-09-07
  • 打赏
  • 举报
回复
to:prog_st(st) __cdecl才可以可变参数吧__stdcall怎么可以呢?
__stdcall主要用于回调函数,供其他语言、或者程序调用的函数,各种导出函数等等。WINAPI
PASCAL 等等宏其实也是__stdcall
meifen 2001-09-07
  • 打赏
  • 举报
回复
ok
prog_st 2001-09-07
  • 打赏
  • 举报
回复
__cdecl、__fastcall、__stdcall是VC的三种调用规范:
调用规范决定从左至右或从右至左的参数传递,有何负责清空堆栈以及函数名称的解释

调用规范 传送顺序 堆栈清除执行者 解释风格
__cdecl 右->左 调用程序 _functionName
__fastcall 右->左 被调用程序 @functionName@nnn
__stdcall 右->左 被调用程序 _functionName@nnn

__fastcall改进了__cdecl的缺省情况,但用在所调用C函数至少有一个参数时,选中该项
编译器将前两个参数送到寄存器ECX DEX,而不是用堆栈,其他参数缺省传入到__cdecl堆栈

__fastcall不许函数使用可变参数长度

__stdcall由Windows API使用,从总体上减小了代码长度,允许使用变长参数表。
onsky2000 2001-09-07
  • 打赏
  • 举报
回复
抱歉,还是没怎么明白。什么时候必须用其中的一个而不能用另一个呢,假如我这样定义
void __cdecl OneFunction()
{……
}
这能告诉编译器什么呢?我又必须做什么呢?
如果我这样定义
void __fastcall OneFunction()
又如何呢?
liu_feng_fly 2001-09-07
  • 打赏
  • 举报
回复
还有,这几种调用格式,在参数压栈的时候顺序好象也不一样,不过我忘了区别了,请大家指点。
liu_feng_fly 2001-09-07
  • 打赏
  • 举报
回复
__cdecl调用者负责清空堆栈(函数返回时),可以实现可变参数
__fastcall函数的前两个参数被放到寄存器中,加快访问速度,所以fast:)
__stdcall,除c、c++以外大多数其他语言的调用格式,由函数清空堆栈(函数返回时),在dll导出函数,回调函数等等要用这种格式。
__stdcall好象运行更安全。因为__cdecl可以是可变参数,函数不知道会有多少个参数传过来,是否正确的传过来,所以运行的时候可能发生错误,如printf等。

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧