在我们的代码中,我们使用指向结构的指针来扣除硬件寄存器的地址,以保持代码的可读性。
例如:
#include <cstdint>
#include <iostream>
struct reg {
uint32_t t;
uint32_t x;
uint32_t value;
};
int main(void)
{
struct reg *r = reinterpret_cast<struct reg *>(0x800000);
std::cerr << &r->value << "\n";
std::cerr << &r->t << "\n";
std::cerr << &r->x << "\n";
return 0;
}
硬件基址是 0x800000 并使用 writeReg(&t->x, 123);
将使其写入 0x800004。
偶然一个volatile
-关键字被错误地放置在结构定义中:
struct reg {
volatile uint32_t t;
volatile uint32_t x;
volatile uint32_t value;
};
现在发生的情况是所有字段都使用 &r->field
偏移量 1 -语法。
使用g++ (Debian 9.2.1-4) 9.2.1 20190821
这里。
使用 printf 和 C 风格的转换在 C 中重写测试,即使使用 volatile,也能再次给出正确的偏移量。
我无法理解为什么 volatile 关键字似乎破坏了指针算术?为什么会这样?发生了什么事?
最佳答案
operator<<
没有过载用于打印指向 volatile
的指针.
编译器找到的最合适的重载是用于打印 bool
的重载。 ,因此您的指针会转换为 bool
.
尝试:
std::cerr << (void *)&r->value << "\n";
关于c++ - 是什么使得 volatile 破坏了结构的指针算术?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57910887/