gpt4 book ai didi

c++ - 标准调用和 cdecl

转载 作者:IT老高 更新时间:2023-10-28 12:03:20 24 4
gpt4 key购买 nike

有(除其他外)两种类型的调用约定 - stdcallcdecl。我对他们有几个问题:

  1. 调用cdecl函数时,调用者如何知道它是否应该释放堆栈?在调用现场,是否调用者知道被调用的函数是 cdecl 还是 stdcall功能 ?它是如何工作的 ?调用者如何知道它是否应该释放堆栈与否?还是链接者的责任?
  2. 如果一个被声明为 stdcall 的函数调用一个函数(它有一个调用约定为 cdecl),或者相反,将这不合适吗?
  3. 一般来说,我们可以说哪个调用会更快 - cdecl 或标准调用?

最佳答案

Raymond Chen gives a nice overview of what __stdcall and __cdecl does .

(1) 调用者“知道”在调用函数后清理堆栈,因为编译器知道该函数的调用约定并生成必要的代码。

void __stdcall StdcallFunc() {}

void __cdecl CdeclFunc()
{
// The compiler knows that StdcallFunc() uses the __stdcall
// convention at this point, so it generates the proper binary
// for stack cleanup.
StdcallFunc();
}

It is possible to mismatch the calling convention ,像这样:

LRESULT MyWndProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam);
// ...
// Compiler usually complains but there's this cast here...
windowClass.lpfnWndProc = reinterpret_cast<WNDPROC>(&MyWndProc);

这么多代码示例都弄错了,这甚至不好笑。应该是这样的:

// CALLBACK is #define'd as __stdcall
LRESULT CALLBACK MyWndProc(HWND hwnd, UINT msg
WPARAM wParam, LPARAM lParam);
// ...
windowClass.lpfnWndProc = &MyWndProc;

但是,假设程序员没有忽略编译器错误,编译器将生成正确清理堆栈所需的代码,因为它会知道所涉及函数的调用约定。

(2) 两种方式都应该有效。事实上,至少在与 Windows API 交互的代码中,这种情况经常发生,因为 __cdecl is the default for C and C++ programs according to the Visual C++ compilerthe WinAPI functions use the __stdcall convention .

(3) 两者之间应该没有真正的性能差异。

关于c++ - 标准调用和 cdecl,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3404372/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com