Questions tagged «calling-convention»

8
什么是__stdcall?
我正在学习Win32编程,其WinMain原型如下所示: int WINAPI WinMain ( HINSTANCE instance, HINSTANCE prev_instance, PSTR cmd_line, int cmd_show ) 我对这个WINAPI标识符的用途感到困惑,发现: #define WINAPI __stdcall 这是做什么的?我对在返回类型之后根本没有东西感到困惑。是__stdcall为了什么 返回类型和函数名称之间有什么含义?

4
为什么Windows64使用与x86-64上所有其他操作系统不同的调用约定?
AMD具有ABI规范,该规范描述了在x86-64上使用的调用约定。除具有自己的x86-64调用约定的Windows外,所有操作系统都遵循它。为什么? 有谁知道这种差异的技术,历史或政治原因,还是纯粹是NIHsyndrome问题? 我知道不同的操作系统可能对更高层次的东西有不同的需求,但这并不能解释为什么例如Windows上的register参数传递顺序却是rcx - rdx - r8 - r9 - rest on stack其他所有人都使用的原因rdi - rsi - rdx - rcx - r8 - r9 - rest on stack。 PS:我知道这些调用约定通常有何不同,并且我知道在需要的地方可以找到详细信息。我想知道的是为什么。 编辑:有关操作方法,请参见Wikipedia条目及其链接。

7
调用堆栈如何工作?
我试图更深入地了解编程语言的低级操作是如何工作的,尤其是它们如何与OS / CPU交互。我可能已经在Stack Overflow上的每个与堆栈/堆相关的线程中阅读了每个答案,它们都很出色。但是还有一件事我还没有完全理解。 在伪代码中考虑这个函数,它通常是有效的Rust代码;-) fn foo() { let a = 1; let b = 2; let c = 3; let d = 4; // line X doSomething(a, b); doAnotherThing(c, d); } 这就是我假设堆栈看起来像第X行的样子: Stack a +-------------+ | 1 | b +-------------+ | 2 | c +-------------+ | 3 | d …

4
为什么T *可以在寄存器中传递,但unique_ptr <T>无法传递?
我正在观看Chandler Carruth在CppCon 2019中的演讲: 没有零成本抽象 在该示例中,他举例说明了您对使用std::unique_ptr&lt;int&gt;over和会产生多少开销而感到惊讶int*。该段大约在时间点17:25开始。 您可以看一下他的示例代码对(godbolt.org)的编译结果 -可以看到,确实,编译器似乎不愿意传递unique_ptr值-实际上,底线是只是一个地址-在寄存器内,仅在直接内存中。 Carruth先生在27:00左右提出的观点之一是,C ++ ABI要求按值传递参数(某些但不是全部;也许-非基本类型?而不是在寄存器中。 我的问题: 这实际上是某些平台上的ABI要求吗?(哪个?)或者在某些情况下可能只是一些悲观? 为什么ABI这样?也就是说,如果结构/类的字段适合寄存器,甚至单个寄存器,为什么我们不能在该寄存器中传递它呢? 近年来,C ++标准委员会是否曾经讨论过这一点? PS-为了不给这个问题留下代码: 普通指针: void bar(int* ptr) noexcept; void baz(int* ptr) noexcept; void foo(int* ptr) noexcept { if (*ptr &gt; 42) { bar(ptr); *ptr = 42; } baz(ptr); } 唯一指针: using std::unique_ptr; void bar(int* ptr) noexcept; void …

3
在Windows上是__cdecl还是__stdcall?
我目前正在为Windows开发一个C ++库,该库将作为DLL分发。我的目标是最大程度地实现二进制互操作性。更确切地说,我的DLL中的功能必须可以从使用多个版本的MSVC ++和MinGW编译的代码中使用,而不必重新编译DLL。但是,我对哪种调用约定最好cdecl还是感到困惑stdcall。 有时我听到诸如“ C调用约定是唯一保证在整个编译器中都相同的声明”之类的语句,这与诸如“的解释存在某些变化cdecl,尤其是如何返回值”之类的语句形成对比。这似乎并未阻止某些库开发人员(如libsndfile)在其分发的DLL中使用C调用约定,而没有任何可见的问题。 另一方面,stdcall调用约定似乎定义明确。据我了解,基本上所有Windows编译器都必须遵循它,因为它是Win32和COM的约定。这是基于这样的假设:没有Win32 / COM支持的Windows编译器将不是很有用。论坛上发布的许多代码片段都声明了函数的功能,stdcall但我似乎找不到一个明确解释原因的帖子。 那里有太多相互矛盾的信息,我进行的每次搜索都会给我不同的答案,但这并不能真正帮助我在两者之间做出决定。我正在寻找一个清晰,详细,有争议的解释,以说明为什么我应该选择一个而不是另一个(或者为什么两者相等)。 请注意,这个问题不仅适用于“经典”的功能,而且还虚成员函数调用,因为大多数客户端代码将与我的DLL通过“接口”,纯虚类接口(以下模式,例如描述在这里和那里)。


1
为什么在不使用堆栈内存时分配堆栈内存?
考虑以下示例: struct vector { int size() const; bool empty() const; }; bool vector::empty() const { return size() == 0; } 生成的汇编代码vector::empty(通过clang,带有优化): push rax call vector::size() const test eax, eax sete al pop rcx ret 为什么要分配堆栈空间?完全不使用。该push和pop可以省略。优化的MSVC和gcc构建也为此功能使用了堆栈空间(请参阅godbolt),因此必须有一个原因。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.