提问人:Dr. Gut 提问时间:1/8/2020 最后编辑:curiousguyDr. Gut 更新时间:1/9/2020 访问量:497
为什么不使用堆栈内存?
Why is stack memory allocated when it is not used?
问:
请看以下示例:
struct vector {
int size() const;
bool empty() const;
};
bool vector::empty() const
{
return size() == 0;
}
生成的汇编代码(通过 clang,经过优化):vector::empty
push rax
call vector::size() const
test eax, eax
sete al
pop rcx
ret
为什么要分配堆栈空间?它根本没有使用。可以省略 和。MSVC 和 gcc 的优化版本也为此函数使用堆栈空间(参见 godbolt),因此一定是有原因的。push
pop
答:
12赞
geza
1/8/2020
#1
它分配堆栈空间,因此堆栈是 16 字节对齐的。这是必需的,因为返回地址需要 8 个字节,因此需要额外的 8 字节空间来保持堆栈 16 字节对齐。
对于某些编译器,可以使用命令行参数来配置堆栈帧的对齐方式。
- MSVC:文档指出堆栈始终是 16 字节对齐的。任何命令行参数都无法更改此设置。godbolt 示例显示,从函数的开头减去 40 个字节,这意味着其他因素也会影响这一点。
rsp
- clang:-
mstack-alignment
选项指定堆栈对齐方式。默认值似乎是 16,尽管没有记录。如果将其设置为 8,则堆栈分配 ( 和 ) 将从生成的汇编代码中消失。push
pop
- gcc:-
mpreferred-stack-boundary
选项指定堆栈对齐方式。如果给定值为 N,则表示 2^N 字节的对齐。默认值为 4,表示 16 个字节。如果将其设置为 3(即 8 字节),则堆栈分配 ( 和 for ) 将从生成的汇编代码中消失。sub
add
rsp
在 godbolt 上查看。
评论
0赞
1/8/2020
这就是为什么 c++ 大师、专家们总是警告:将结构/类成员按最长/最大大小到最小的顺序排列......只有这样,它才会正确有效
0赞
Dr. Gut
1/9/2020
@geza:谢谢。我为其他两个编译器做了一些研究,并把它写到你的答案中。喜欢吗?
2赞
geza
1/9/2020
@Dr.Gut:谢谢,你让答案变得更好、更完整。请注意,堆栈对齐通常记录在系统的 ABI 中(例如,对于某些系统,以下是文档:github.com/hjl-tools/x86-psABI/wiki/X86-psABI)。
0赞
Dr. Gut
1/9/2020
@geza:谢谢。
上一个:无分配枚举和处理
评论
this
vector::size()
vector::size()
vector::empty()
empty()