C:寄存器地址还是内存地址?

标签 c pointers processor

我对 C 中的关键字“register”有点困惑。 它似乎告诉编译器它应该存储在一个寄存器中,这意味着我的一些变量存储在寄存器中,一些存储在内存中?如果是这样,有没有办法找出我的值是存储在寄存器中还是内存中?

例如:

int *x =  (int*) 0x1234;

X现在好像不指向一个寄存器,因为这样的地址是给内存用的。 但我曾多次尝试找到一个不同的地址(也使用“register”关键字)。即使在互联网上,似乎也没有人关心。

所以我的主要问题是:当指针指向寄存器时,指针中的地址看起来如何?

编辑:我在另一个问题的问题末尾找不到我的主要问题的答案。我的问题不是关于关键字“注册”,我只是提到了它。

最佳答案

存储类说明符 register是在 C 语言的第一个版本中创建的,用于指示编译器使用其中一个处理器寄存器来保存具有允许更快访问范围的变量。当时代码编写需要程序员的大量关注,因为编译器并不聪明,无法检测或纠正错误,从而导致错误代码。

无论如何,在 C 标准的发展过程中,有一些技巧使一些细节难以理解。

存储类说明符 register是其中之一。因此,在评论它们之前,让我们开始查看规范。

来自 ISO/IEC 9899:2011,C11 标准:

§6.7.1 Storage-class specifiers

A declaration of an identifier for an object with storage-class specifier register suggests that access to the object be as fast as possible. The extent to which such suggestions are effective is implementation-defined. (See note 119)

还有注释 119:

NOTE

The implementation may treat any register declaration simply as an auto declaration. However, whether or not addressable storage is actually used, the address of any part of an object declared with storage-class specifier register cannot be computed, either explicitly (by use of the unary & operator as discussed in 6.5.3.2) or implicitly (by converting an array name to a pointer as discussed in 6.3.2.1). Thus, the only operator that can be applied to an array declared with storage-class specifier register is sizeof.

这意味着存储说明符 register是对编译器的建议使用处理器寄存器或任何其他方法来尽可能快地访问变量,但编译器可以做出不同的决定。它可以将声明的变量视为标准 auto变量。

在最后一种情况下,从技术上来说,获取存储地址是可能的,但正如注释中所解释的那样,这是标准明确禁止的,而且在 § 的约束中也强制执行6.5.3.2 地址和间接运算符:

The operand of the unary & operator shall be either a function designator, the result of a [] or unary * operator, or an lvalue that designates an object that is not a bit-field and is not declared with the register storage-class specifier.

当然,一些不兼容的编译器可能会让您应用运算符。

现在回到你的问题:

  1. int *x = (int*) 0x1234; X does not seem to point on a register now, because such addresses are for memory. But I have tried several times to find a different looking address (also using "register" key word). Even on the internet nobody seems to care.

您的示例是错误的,您正在声明一个指向 int 的指针并为其分配任意地址。这与register无关存储说明符。

声明register int *x = (int*) 0x1234;然后尝试应用 &接线员到 xint **pp = &x; (请注意,我们正在声明一个指向指向 int 的指针的指针,这就是我们获取指向 int 的指针的地址)。

您会在兼容的编译器上遇到错误。

  1. So my main quesition: How does the address in a pointer look when it points on a register?

答案很简单:它不像任何东西,因为它不存在于标准 C 中

关于C:寄存器地址还是内存地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50296838/

相关文章:

c - 下面的代码有什么错误?

pointers - 从函数中的局部变量返回指针

c - 在什么情况下 C 需要指向指针的指针?

c - 附加到链表的元素在附加后似乎发生了变化

随着线程池大小的增加,Java 多线程性能最差

c - 为什么 printf() 在下面的代码中打印 0 而不是 10?

c - 帧指针/程序计数器/数组溢出

c - 字符串使用的字符单元格数

c# - 方法的代码块在执行时是在栈中还是堆中?

我可以从 GPIO 的输出引脚读取有效信号吗?