当前位置: 首页 > 知识库问答 >
问题:

是否允许C编译器将顺序赋值合并到volatile变量?

梁晋鹏
2023-03-14

我有一个理论(非确定性,难以测试,从未发生在实践中)硬件问题报告硬件供应商,其中双字写入特定内存范围可能破坏任何未来的总线传输。

虽然我在C代码中没有任何明确的双词写入,但我担心编译器(在当前或未来的实现中)被允许将多个相邻的词赋值合并为单个双词赋值。

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

示例:

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;

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

共有1个答案

丰辰沛
2023-03-14

对于易失性对象上的操作和实际机器上的操作之间的任何关系,C标准是不可知的。虽然大多数实现将指定像*(char volate*)0x1234=0x56;这样的构造将生成值为0x90的字节存储到硬件地址0x1234,但一个实现可以在空闲时为例如8192字节数组分配空间,并指定*(char volate*)0x1234=0x56;将立即将0x56存储到该数组的元素0x1234,而不必对硬件地址0x1234做任何事情。可替换地,实现可包括某些进程,该进程将碰巧在该阵列的0x1234中的任何内容周期性地存储到硬件地址0x56。

从抽象机器的角度来看,对单个线程内易失性对象的所有操作都被视为绝对有序的,这才是一致性所需要的。从标准的观点来看,实现可以以他们认为合适的任何方式将这样的访问转换为真实的机器操作。

 类似资料: