【发布时间】:2019-09-12 16:19:43
【问题描述】:
在我们的代码中,我们使用指向结构的指针来扣除硬件寄存器的地址以保持代码的可读性。
例如:
#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-keyword 错误地放置在结构定义中:
struct reg {
volatile uint32_t t;
volatile uint32_t x;
volatile uint32_t value;
};
现在发生的事情是所有字段的偏移量都为 1,使用 &r->field-syntax。
在这里使用g++ (Debian 9.2.1-4) 9.2.1 20190821。
使用 printf 和 C-style-cast 在 C 中重写测试,即使使用 volatile,也会再次给出正确的偏移量。
我无法理解为什么 volatile-keyword 似乎破坏了指针算术?为什么呢?发生了什么?
【问题讨论】: