繁体   English   中英

C++ volatile:保证 32 位访问?

[英]C++ volatile: guaranteed 32-bit accesses?

在我的Linux C++ 项目中,在执行mmap后,我使用uint32_t 指针访问的物理地址空间中的某处映射了一个硬件内存区域

应用程序的发布版本SIGBUS(总线错误)而崩溃。

发生这种情况是因为编译器使用 64 位访问优化了对上述硬件内存的访问,而不是坚持 32 位 => 总线错误,硬件内存只能使用 32 位读/写访问

我将uint32_t 指针标记为volatile

有用。 对于这一特定的代码部分,至少 因为编译器被告知不要重新排序。 大多数情况下,它必须重新排序才能优化。

我知道 volatile 控制编译器何时访问内存。 问题是: volatile 是否也告诉编译器如何访问内存,即完全按照程序员的指示访问它 我是否保证编译器将始终坚持对 volatile uint32_t 缓冲区进行 32 位访问?

例如, volatile 是否还保证编译器也将使用 32 位读/写访问以下代码片段中对 2 个连续 32 位值的连续 2 次写入

void aFunction(volatile uint32_t* hwmem_array)
{
    [...]

    // Are we guaranteed by volatile that the following 2 consecutive writes, in consecutive memory regions
    // are not merged into a single 64-bit write by the compiler?
    hwmem_array[0] = 0x11223344u;
    hwmem_array[1] = 0xaabbccddu;

    [...]
}

我想我已经回答了我自己的问题,如果我错了,请纠正我。

C99 标准草案http : //www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf

引号:

6 具有 volatile 限定类型的对象可能会以实现未知的方式进行修改或具有其他未知的副作用 因此,任何引用此类对象的表达式都应严格按照抽象机的规则进行评估如 5.1.2.3 中所述 此外,在每个序列点,最后存储在对象中的值应与抽象机规定的值一致,除非被前面提到的未知因素修改。

第 5.1.2.3 节:

2访问易失性对象、修改对象、修改文件或调用执行任何这些操作的函数都是副作用,它们是执行环境状态的变化。 表达式的计算可能会产生副作用 在称为序列点的执行序列中的某些指定点处,先前评估的所有副作用都应完成,并且后续评估的副作用不应发生 (序列点的摘要在附录 C 中给出。)

5 对一致实现的最低要求是: — 在序列点,易失性对象先前访问已完成且后续访问尚未发生的意义上稳定

附录 C(资料性) 序列点:

1 以下是5.1.2.3中描述的序列点:

[…]

完整表达式结尾:初始化程序(6.7.8); 表达式语句中的表达式(6.8.3); 选择语句的控制表达式(if 或 switch)(6.8.4); while 或 do 语句的控制表达式 (6.8.5); for 语句的每个表达式(6.8.5.3); return 语句中的表达式 (6.8.6.4)。

因此,理论上我们可以保证在任何涉及 volatile 对象的表达式结束时,都会按照编译器的指示写入/读取 volatile 对象

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM