c++ - __cdecl 导致比 __stdcall 更大的可执行文件?

标签 c++ c compiler-construction calling-convention

我发现了这个:

Because the stack is cleaned by the called function, the __stdcall calling convention creates smaller executables than __cdecl, in which the code for stack cleanup must be generated for each function call.

假设我有两个函数:

void __cdecl func1(int x)
{
    //do some stuff using x
}

void __stdcall func2(int x, int y)
{
    //do some stuff using x, y
}

main() 中:

int main()
{
    func1(5);
    func2(5, 6);
}

IMO,main() 负责清理对 func1(5)func2 的调用堆栈将清理对 func2(5,6) 的调用堆栈,对吗?

四个问题:

1.对于在main()中调用func1main负责清理堆栈,编译器也一样在调用 func 之前和之后插入一些代码(清理堆栈的代码)?像这样:

int main()
{
    before_call_to_cdecl_func(); //compiler generated code for stack-clean-up of cdecl-func-call
    func1(5);
    after_call_to_cdecl_func(); //compiler generated code for stack-clean-up of cdecl-func-call

    func2(5, 6);
}

2.main()中调用func2,清理堆栈是func2自己的工作,所以我假设,在调用 func2 之前或之后,不会在 main() 中插入任何代码,对吗?

3.因为func2__stdcall,所以我推测,编译器会像这样自动插入代码(清理堆栈):

void __stdcall func1(int x, int y)
{
    before_call_to_stdcall_func(); //compiler generated code for stack-clean-up of stdcall-func-call
    //do some stuff using x, y
    after_call_to_cdecl_func(); //compiler generated code for stack-clean-up of stdcall-func-call
}

我想对吧?

4.最后,回到引用的话,为什么 __stdcall__cdecl 产生更小的可执行文件?而且 linux 中没有 __stdcall 这样的东西,对吧?是不是linux elf总是比win下的exe大?

最佳答案

  1. 它只会在调用后插入代码,即重置堆栈指针,只要有调用参数。*
  2. __stdcall 在调用点不生成清理代码,但是,应该注意编译器可以将多次 __cdecl 调用的堆栈清理累积到一次清理中,或者它可以延迟清理以防止管道停顿。
  3. 忽略此示例中的倒置顺序,不,它只会插入代码来清理 __cdecl 函数,函数参数的设置是不同的(不同的编译器生成/偏好不同的方法)。
  4. __stdcall 更像是 Windows 的东西,参见 this .二进制文件的大小取决于对 __cdecl 函数的调用次数,更多调用意味着更多清理代码,而 __stdcall 只有 1 个清理代码实例。但是,您不会看到大小增加太多,因为每次调用最多只有几个字节。

*区分清理和设置调用参数很重要。

关于c++ - __cdecl 导致比 __stdcall 更大的可执行文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9173051/

相关文章:

c++ - 使 struct volatile 会使它的所有成员 volatile 吗?

c++ - 在C++中使循环变量成为常量

c++ - 不使用动态内存分配的 Pimpl 习惯用法

c - 为什么在将二维数组传递给 C 函数时必须提供维度?

c - build 一台扫描仪。识别代币

c++ - 使用分配给函数返回值的局部变量或直接使用函数

c++ - 令人惊讶的基准测试结果

c - 避免 printf() 中的尾随零

c - C中字符串的加减法(编码/解码)

c - 编译器警告消息