我该怎么做才能保证我的C(或C99)编译器在所有情况下都只能生成完整的32位宽读写?
例如,如果我执行这样的读 – 修改 – 写操作:
volatile uint32_t* p_reg = 0xCAFE0000; *p_reg |= 0x01;
我不希望编译器明智地知道只有底部字节发生变化并产生8位宽的读/写.由于机器代码在x86上的8位操作通常更密集,我害怕不必要的优化.一般情况下禁用优化不是一种选择.
—–编辑——-
一篇有趣且非常相关的论文:http://www.cs.utah.edu/~regehr/papers/emsoft08-preprint.pdf
解决方法
6.7.3 / 6“类型限定词”说:
An object that has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects. Therefore any expression referring to such an object shall be evaluated strictly according to the rules of the abstract machine,as described in 5.1.2.3. Furthermore,at every sequence point the value last stored in the object shall agree with that prescribed by the abstract machine,except as modified by the unknown factors mentioned prevIoUsly. What constitutes an access to an object that has volatile-qualified type is implementation-defined.
5.1.2.3“程序执行”(除其他外)说:
In the abstract machine,all expressions are evaluated as specified by the semantics.
接下来是一个通常称为“as-if”规则的句子,如果最终结果相同,则允许实现不遵循抽象机器语义:
An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced (including any caused by calling a function or accessing a volatile object).
但是,6.7.3 / 6基本上表示表达式中使用的volatile限定类型不能应用“as-if”规则 – 必须遵循实际的抽象机器语义.因此,如果取消引用指向易失性32位类型的指针,则必须读取或写入完整的32位值(取决于操作).