[问题] 区域变量是如何存在内存上的?

楼主: wei115 (ㄎㄎ)   2019-12-08 16:50:35
感觉C点比较弱,可能和ASM比较有关系,但这里人多,就发在这了:p
如题
小弟最近在写一个简单的C编译器,但对于区域变量是如何放在堆叠上的有些迷惑
例如
int main()
{
int a = 111;
if(a)
int b = 222;
int c = 333;
return 0;
}
一开始我是想说,编译器是在要使用时才把变量push到堆叠上的
像是遇到a = 111,就在堆叠上push一个111,然后只有if成立时才把222 push到堆叠上,
反之则跳过
可是看了好几个组合语言的范例(x86 Arm),好像会先计算在这函数中所有可能会用到变
数大小然后一次性push到堆叠上
例如刚刚的C程式,如果if成立会有a、b、c三个int,不成立会有a、c两个int
而看到的实作则是不管有没有b都先分配空间给他
但以C来说,在if内宣告的变量,他的生命周期应该就只在if内,但如果以这样的实作,
在if内的变量,只要知道他的内存位置,就算在if外也能存取(因为有事先分配空间,
而且没有回收),不太理解为什么要这么做
有没有相关资料是讲这方面细节的,谢谢
(写完后发现C点真的好少.....会不会被删阿orz....)
作者: jerryh001   2019-12-08 17:16:00
因为快 一编译下去相对位置就固定了 而且scope只有在高阶的时候才有意义 进到组合语言后没在管这个
作者: Fenikso (薪水小偷)   2019-12-08 17:19:00
你要怎么只回收b, 移动rsp吗? 这样也没有真的回收喔
作者: harryooooooo (真_终极萝莉控Ecstasy_)   2019-12-08 17:20:00
照你说的在进到scope时才分配的话,就跟把scope当function call差不多意思了。语意上没什么问题但是会有效能损失吧,只有看过把function inline的没看过反过来的。而且还要重新维护scope外的变量的offset,损失应该真的不小。
作者: Lipraxde (Lipraxde)   2019-12-08 18:18:00
如果 backend 是 stack architecture 的话就会看到你说的那种方式了,你看的范例应该都是 register architecture
作者: iaminanl (好MAN)   2019-12-08 19:31:00
如果-O都没有开,compiler就不会有优化(security concern是优化的一部分)-O0: https://gcc.godbolt.org/z/dMdStp-O1: https://gcc.godbolt.org/z/cTzgRs 都不见了每个compiler都差不多,可以做多一点实验看看
作者: suhorng ( )   2019-12-09 09:06:00
直接预先算好的优点前面推文说过了 另外 push/pop 会改变 stack pointer, 反而不一定有固定 %rsp + 位移快另外, 最后生命周期那段有错. 内存空间在那里并不代表变量还活着. 因为已经结束了生命周期, 再去存取是未定义的, 甚至同样的位址再分配给别的变量也有可能https://gcc.godbolt.org/z/EmHfj5 这里 b 和 d 就是
作者: jepk007 (NW-吉普)   2019-12-09 10:13:00
if内变量的生命周期不也是整个函数吗
作者: xam (听说)   2019-12-09 12:06:00
自修吗? 这些东西计算机组织/结构,编译器的课程会学到..
作者: nullptr (SIGSEGV)   2019-12-24 03:57:00
if内变量的生命周期只在if内喔, 出了之后再去读是syntaxerror; 如果把&b存进pointer然后去读的话是UB因为是UB所以编译器可能拿B的空间给C用

Links booklink

Contact Us: admin [ a t ] ucptt.com