In our code we use pointers to structures to deduct addresses of hardware registers to keep the code readable.
For example:
#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;
}
The hardware-base-address is 0x800000 and using writeReg(&t->x, 123);
will make it write to 0x800004.
By accident a volatile
-keyword was wrongly placed in the structure-definition:
struct reg {
volatile uint32_t t;
volatile uint32_t x;
volatile uint32_t value;
};
What happened now is that all fields have the offset 1 using the &r->field
-syntax.
Using g++ (Debian 9.2.1-4) 9.2.1 20190821
here.
Rewriting the test in C using printf and a C-style-cast gives again the correct offset even with volatile.
I'm unable to unable to understand why the volatile-keyword seems to break pointer-arithmetic? Why is that so? What is happening?