2

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?

Patrick B.
  • 11,773
  • 8
  • 58
  • 101

1 Answers1

5

There is no overload of operator<< for printing pointers to volatile.

The best suitable overload your compiler finds is the one for printing bool, so your pointers get converted to bool.

Try:

std::cerr << (void *)&r->value << "\n";
HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207