Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么堆栈内存在未使用时被分配?_C++_Code Generation_Calling Convention_Abi_Stack Allocation - Fatal编程技术网

C++ 为什么堆栈内存在未使用时被分配?

C++ 为什么堆栈内存在未使用时被分配?,c++,code-generation,calling-convention,abi,stack-allocation,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生成的汇编代码(通过叮当声和优化): 它为什么分配堆栈空间?它根本不被使用。可以省略推送和弹出。MSVC和gcc的优化版本也为此函数使用堆栈空间(请参见上),因此一定有原因。它分配堆栈空间,因此堆栈是16字节对

考虑以下示例:

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

bool vector::empty() const
{
    return size() == 0;
}
vector::empty
生成的汇编代码(通过叮当声和优化):


它为什么分配堆栈空间?它根本不被使用。可以省略
推送
弹出
。MSVC和gcc的优化版本也为此函数使用堆栈空间(请参见上),因此一定有原因。

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

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

  • MSVC:表示堆栈始终是16字节对齐的。没有人能改变这一点。godbolt示例显示,在函数开始时,从
    rsp
    中减去40个字节,这意味着其他因素也会影响这一点
  • clang:该选项指定堆栈对齐方式。看起来,默认值是16,尽管没有记录在案。如果将其设置为8,堆栈分配(
    push
    pop
    )将从生成的汇编代码中消失
  • gcc:该选项指定堆栈对齐方式。如果给定值为N,则表示2^N字节的对齐。默认值为4,表示16个字节。如果将其设置为3(即8个字节),则堆栈分配(
    sub
    add
    for
    rsp
    )将从生成的汇编代码中消失

查看。

您是否考虑了隐式
参数?@Bob\uuuu:不。我为什么要这样做<示例中没有定义代码>向量::大小()来模拟它不是内联的。那么,编译器如何优化它不知道的东西呢?@Bob\uuuuu:我认为,知道
向量::大小()
的实现与为
向量::空()
分配或不分配堆栈帧无关。在<代码> EMPTY()/<代码>中,它只是调用,不管是什么,调用一个返回某些东西的函数,你需要空间(如果你不知道更好的话)。这就是为什么C++专家、专家一直警告:把结构/类成员按最长/最大的大小排列成最小…只有这样才是正确的efficient@geza:谢谢。我为另外两个编译器做了一些研究,并将其写入了您的答案中。你喜欢吗?@Dr.Gut:谢谢,你把答案做得更好更完整了。请注意,堆栈对齐通常记录在系统的ABI中(例如,对于某些系统,以下是文档:)。@geza:谢谢。
push    rax
call    vector::size() const
test    eax, eax
sete    al
pop     rcx
ret