硬件供应商报告了一个理论上的(不确定的,难以测试的,实际上从未发生过)硬件问题,其中对特定内存范围的双字写入可能会 destruct 任何future 的总线传输.

虽然我没有在C代码中显式地编写任何双字代码,但我担心编译器(在当前或将来的实现中)会被允许将多个相邻的单词赋值合并成单个双字赋值.

编译器不允许对挥发物的赋值进行重新排序,但(对我来说)不清楚合并是否算作重新排序.我的直觉是这样的,但我以前被语言律师纠正过!

例子:

typedef struct
{
   volatile unsigned reg0;
   volatile unsigned reg1;
} Module;

volatile Module* module = (volatile Module*)0xFF000000u;

// two word stores, or one double-word store?
module->reg0 = 1;
module->reg1 = 2;

(我会单独询问我的编译器供应商,但我很好奇该标准的规范/社区解释是什么.)

推荐答案

volatile的行为似乎取决于实现,部分原因是有一句奇怪的话说:"对具有可变限定类型的对象的访问是由实现定义的".

在ISO C 99第5.1.2.3节中,还有:

3在抽象机中,所有表达式都按照语义指定的方式求值.一个 如果实际实现可以推导出它的表达式的一部分,则它不需要计算表达式的一部分 值,并且不会产生所需的副作用(包括由 调用函数or accessing a volatile object).

因此,尽管要求必须按照抽象语义(即不优化)来处理volatile对象,但奇怪的是,the abstract semantics itself允许消除死代码和数据流,这些都是优化的示例!

恐怕要知道volatile会做什么,不会做什么,您必须参考编译器的文档.

C++相关问答推荐

为什么在Linux(特别是Ubuntu 20.04LTS)上,POSIX共享内存对象在重启后仍然存在,然后突然变成了根用户?

如何在Visual Studio代码中关闭此函数名称显示功能?

以前版本的tty_ldisc_ops.ioctl()是否也需要文件参数?

当execvp在C函数中失败时杀死子进程

如何在C宏中确定 struct 中元素的类型?

用C宏替换strncMP函数中的参数

N的值设置为0或1(未定义的行为),而我正在try 学习realloc和Malloc的用法

用C++实现余弦函数

无法在OpenGL上绘制三角形

如何读取文件并将内容保存在字符串中?(在C语言中,没有崩溃或核心转储错误)

处理EPOLL_WAIT中的接收数据和连接关闭信号

从CentOS 7到Raspberry PI 2B的交叉编译-无法让LIBC和System Include标头一起工作

为什么我的二叉树删除删除整个左部分的树?

在文件描述符上设置FD_CLOEXEC与将其传递给POSIX_SPOWN_FILE_ACTIONS_ADCLOSE有区别吗?

浮动目标文件,数据段

为什么写入关闭管道会返回成功

在 C 中的 scanf() 格式说明符中使用宏获取字符串长度

无法在 C 中打开文本文件,我想从中读取文本作为数据并将其写入数组

在 printf() 格式说明符中使用字段宽度变量

CS50多项,印刷优胜者