我想知道,我们如何确定用register
说明符定义的变量是否存储在CPU寄存器中?
答案 0 :(得分:8)
基本上,你不能。 C标准中没有任何内容可以让你控件。
使用register
关键字为编译器提供了提示,即变量可能存储在寄存器中(即允许最快的访问)。编译器可以自由地忽略它。每个编译器都可以采用不同的方式接受/拒绝提示。
引用C11
,章节§6.7.1,(强调我的)
具有存储类说明符
register
的对象的标识符声明 建议尽可能快地访问对象。 这种程度 建议是有效的是实施定义。
FWIW,大多数现代编译器可以检测最常用的变量并将它们分配到实际的寄存器中,如果需要。请记住,CPU寄存器是一种稀缺资源。
答案 1 :(得分:4)
反汇编代码并检查。在这一点上可能并不十分清楚,因为变量并不存在,它们只是将生产者与消费者联系起来的名称。因此,没有必要为该变量保留一个寄存器 - 可能它完全消失,也许它在其生命周期内存在于几个寄存器中,可能没有上述任何一个。
答案 2 :(得分:1)
从历史上看,register
关键字是几十年前引入的,作为编译器的优化提示。如今,当处理器具有更多通用寄存器时,编译器通常会将变量放在寄存器中,即使没有被告知也是如此(当代码使用优化编译时)。
只是一个提示,而不是强制执行,你不能做任何强迫它。但是,您可以在汇编程序中编写该部分代码。这样您就可以完全控制变量的存储位置。
答案 3 :(得分:1)
如果变量存储在寄存器中,则意味着它不存储在存储器中。 因此,牛市的目标是尝试使用printf访问变量的地址。如果输出给出一些地址,结论是它存储在内存中,因此它将充当自动存储类变量(并且它不存储在寄存器中)。 但如果它给出错误“内置函数'printf'的不兼容隐式声明”,那么这意味着变量存储在寄存器中,并且表现为寄存器存储类变量..
答案 4 :(得分:0)
也许调用汇编指令会有所帮助:
/// Function must be something like this:
int check_register_storing()
{
__asm__ (
pushad // Save registers
and ebx, ebx // Set Zero
and eax, eax
and ecx, ecx
and edx, edx
);
// Set test number.
register int a = 8; // Initial value;
int from_register = 0;
asm(
add eax, ebx // If, 'a' variable set on CPU register,
add eax, ecx // Some of main usage registers must contain 8
add eax, edx // Others must contain 0
mov %from_register, eax
popad // Return default parameters to registers
}
/// Check result
printf( "Original saved number: %d, Returned number from main registers: %d\n", a, from_register );
}
答案 5 :(得分:0)
我不知道我是对还是错,但我们知道普通变量存储在有地址的内存中,但我们知道如果我们写register int a;
,那么可能会为变量,但我们知道寄存器有名字,而不是地址,所以我们不能分配指针指向寄存器,因为指针只存储地址,所以如果我们这样写:-
#include<stdio.h>
int main()
{
register int reg = 5;
int *p = ®
printf("%d",reg);
}
然后它应该给出错误为:“寄存器变量'reg'请求的地址”如果寄存器已成功分配给我们的变量,并且如果没有分配寄存器,则可以将内存地址分配给指针,因此应该没有错误. 重要提示:-这是我在 stackoverflow 上的第一个答案,我可能错了,如果我错了,请纠正我,我还在学习。