c++ - 为什么不使用时分配堆栈内存?

标签 c++ code-generation calling-convention abi stack-allocation

考虑以下示例:

struct vector {
    int  size() const;
    bool empty() const;
};

bool vector::empty() const
{
    return size() == 0;
}

vector::empty 生成的汇编代码(通过叮当,经过优化):
push    rax
call    vector::size() const
test    eax, eax
sete    al
pop     rcx
ret

为什么要分配堆栈空间?它根本没有被使用。 pushpop可以省略。 MSVC 和 gcc 的优化构建也为此函数使用堆栈空间(参见 godbolt 上的说明),所以一定有原因。

最佳答案

它分配堆栈空间,因此堆栈是 16 字节对齐的。它是必需的,因为返回地址需要 8 个字节,因此需要额外的 8 个字节空间来保持堆栈 16 字节对齐。

对于某些编译器,可以使用命令行参数配置堆栈帧的对齐方式。

  • MSVC : documentation说堆栈总是 16 字节对齐。否 command line argument可以改变这一点。 Godbolt 示例显示,从 rsp 中减去了 40 个字节。在函数的开头,这意味着其他东西也会影响它。
  • 叮当 : -mstack-alignment 选项指定堆栈对齐。似乎默认值是 16,尽管没有记录。如果将其设置为 8,堆栈分配( pushpop )将从生成的汇编代码中消失。
  • gcc : -mpreferred-stack-boundary 选项指定堆栈对齐。如果给定的值为 N,则表示 2^N 字节对齐。默认值为 4,即 16 个字节。如果将其设置为 3(即 8 个字节),堆栈分配( subadd 用于 rsp )将从生成的汇编代码中消失。

  • 查看 godbolt .

    关于c++ - 为什么不使用时分配堆栈内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59636935/

    相关文章:

    c - HDF5 C代码生成

    c++ - 类变量在离开范围后会自动删除,我该如何防止这种情况发生?

    pointers - 我们是否在 Go 中过度使用了传递指针?

    c++ - 如何获取局域网内所有IP地址的列表?

    java - 如何在JavaPoet中添加 'Any Type'问号?

    c++ - 在递归函数中递增

    java - 在 Maven 中生成一个 Version.java 文件

    c++ - 使用调用约定 fastcall 的任何实际用例?

    c++ - auto* 在编译时有用还是 auto 关键字就足够了?

    c++ - CMake、VTK8 和 Embarcaderos Clang 编译器