存储在寄存器中的变量的地址

Már*_*iva 12 c

如果在我的代码中某处,我使用变量的地址(例如,将其传递给其他函数),编译器会自动选择将其存储在内存中吗?(而不是将其存储在寄存器中的可能性).

否则,如果我要求变量的地址(存储为寄存器)会发生什么?我知道我们不能将变量的地址显式设置为register(register int c).

编辑:

例如,如果我做了类似的事情

int c = 1;
print("Address of c: %p", &c);
Run Code Online (Sandbox Code Playgroud)

那么这个变量不能存储在寄存器中,不是吗?编译器会自动将其设置为存储在内存中吗?否则(如果它只是存储在一个寄存器中),屏幕上显示的地址是什么?

Gen*_*ene 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.
}
Run Code Online (Sandbox Code Playgroud)

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