12

If somewhere in my code, I use the address of a variable (pass it to some other function, for example), the compiler will automatically choose to store it in memory? (as opposed to the possibility of storing it in a register).

Otherwise, what happens if I ask for the address of a variable like that (stored as register)? I know we can't take the address of variables explicitly set to register (register int c).

EDIT:

For example, if i do something like

int c = 1;
print("Address of c: %p", &c);

Then this variable couldn't be stored in a register, could it? The compiler would automatically set it as stored in memory? Otherwise (if it is just stored in a register), what would be the address shown in the screen?

4

3 回答 3

19

首先,C 标准禁止获取声明的变量的地址register,就像它对structs 中的位域所做的那样。

对于非注册(“自动”)变量,简短的回答是肯定的。优化器最简单的策略是立即溢出地址被占用的变量。

“溢出”只是寄存器分配文献中的一个术语,意思是“决定放置在内存中而不是寄存器中”。

一个复杂的优化器可以进行别名分析并且仍然在寄存器中保存一个值,即使它的地址已经被占用。只要可以证明生成的指针不可能用于更改值,这都是可能的。

另一个相关的优化是实时范围分割。这允许将变量存储在寄存器中,用于保存有用值的部分指令范围(其“有效范围”),并溢出到其他部分。在这种情况下,溢出的部分将对应于指针可能用于更改变量值的位置。例如:

x = 3;
... lots of computations involving x
if T {
  // SPILL HERE, so store register holding x to memory
  int *p = &x;
  ... lots of computations, perhaps using p to change x
  *p = 2;
  // DONE SPILL HERE, so reload register
  ... more code here not using p to change x.
}
else {
  ... lots of computations involving x.
}

此代码的积极优化器可能会为 x 分配堆栈位置,但将其加载到代码顶部的寄存器中,除了标记为 SPILL 的区域外,将其保留在那里。该区域将被寄存器存储到内存和匹配的寄存器加载所包围。

于 2013-05-20T03:53:07.720 回答
3

通过获取其地址,您强制编译器将变量放入内存中,而不是将其优化到寄存器中。

这个答案有一些很好的信息:寄存器变量的地址

于 2013-05-20T03:52:30.393 回答
0

编译器必须非常小心优化指针,因为任何人都可以在幕后更改它们。这就是为什么优化关键字如restrict存在(告诉编译器在任何地方都没有指针的其他副本)。所以一般你不会有你描述的情况。

于 2013-05-20T03:53:05.837 回答