繁体   English   中英

为什么后续的Rust变量增加堆栈指针而不是减少堆栈指针?

[英]Why do subsequent Rust variables increment the stack pointer instead of decrementing it?

我觉得奇怪的是,当您在Rust中创建静态分配的变量时,似乎随着堆栈指针的增加而增加。 我知道不是这种情况,因为堆栈指针随着分配的内存而减少。

如果要在C中做同样的事情,我会发现随着创建更多变量,堆栈指针会减少。

为什么这样呢? Rust编译器是否从下至上而不是从上至下分配这些?

fn main() {
    let i1 = 1;
    let i2 = 1;
    let i3 = 1;
    println!("i1 : {:?}", &i1 as *const i32);
    println!("i2 : {:?}", &i2 as *const i32);
    println!("i3 : {:?}", &i3 as *const i32);
}

当我运行该程序时,我收到以下消息:

i1 : 0x9f4f99fb24
i2 : 0x9f4f99fb28
i3 : 0x9f4f99fb2c

如果我使用C,我将得到:

i1 : 0x9f4f99fb2c
i2 : 0x9f4f99fb28
i3 : 0x9f4f99fb24

将堆栈视为功能堆栈帧序列,而不是可变地址序列。 不管堆栈增长的方向如何,它都会以整个堆栈帧的增量增长,每个堆栈帧的大小各不相同。

函数的堆栈框架的布局具有将变量绑定到的固定位置,类似于结构,但是不能保证框架内绑定的确切顺序。 如果可以使该功能使用不同的布局更有效地利用空间,则可能会做到。 例如:

fn main() {
    let i1: i32 = 1;
    let i2: i64 = 2;
    let i3: i32 = 3;
    println!("i1 : {:?}", &i1 as *const i32);
    println!("i2 : {:?}", &i2 as *const i64);
    println!("i3 : {:?}", &i3 as *const i32);
}

// i1 : 0x7fff4b9271fc
// i2 : 0x7fff4b927200
// i3 : 0x7fff4b92720c

在此, i3 i2 之前存储。 i64需要与64位的倍数对齐,因此将两个i32存储在一起而不是i32是更紧凑的。 这不会发生在调试版本中,编译器也可以选择存储i3先用同样的效果,所以我们不能和不应该依赖于这种排序。

也有可能出于任何其他优化原因(例如缓存访问效率)对变量进行重新排序。


要查看堆栈确实向下增长,请考虑一个具有多个功能的示例:

fn main() {
    let i1 = 1;
    println!("i1 : {:?}", &i1 as *const i32);

    another();
}

#[inline(never)]
fn another() {
    let i2 = 2;
    println!("i2 : {:?}", &i2 as *const i32);
}

// i1 : 0x7fffc7601fbc
// i2 : 0x7fffc7601f5c

anothermain调用,因此其堆栈帧具有较低的地址。 注意,我不得不强制编译器不要内联函数,否则组合的布局将是任意的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM