是什么使volatile破坏了结构的指针算法?

Pat*_* B. 2 c++ pointers structure

在我们的代码中,我们使用指向结构的指针来推导硬件寄存器的地址,以保持代码的可读性。

例如:

#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;
}
Run Code Online (Sandbox Code Playgroud)

hardware-base-address是0x800000,使用writeReg(&t->x, 123);它将使它写入0x800004。

偶然地,volatile-keyword被错误地放置在结构定义中:


struct reg {
    volatile uint32_t t;
    volatile uint32_t x;
    volatile uint32_t value;
};
Run Code Online (Sandbox Code Playgroud)

现在发生的是,所有字段都使用&r->field-syntax 偏移了1 。

g++ (Debian 9.2.1-4) 9.2.1 20190821在这里使用。

使用printf和C-style-cast在C中重写测试,即使使用volatile也可以再次提供正确的偏移量。

我无法理解为什么volatile关键字似乎破坏了指针算术?为什么?怎么了?

Hol*_*Cat 5

没有operator<<打印指向的指针的重载volatile

编译器找到的最适合的重载是要打印的重载bool,因此您的指针将转换为bool

尝试:

std::cerr << (void *)&r->value << "\n";
Run Code Online (Sandbox Code Playgroud)