兼容C90的编译器是否必须考虑CPU的指令重新排序?

Her*_*che 4 c compiler-construction assembly standards

考虑以下代码:

volatile int a;
volatile int b;
int x;

void func() {
    a = 1;
    x = 0; /* dummy statement */
    b = 2;
}
Run Code Online (Sandbox Code Playgroud)

在此代码段中,对x的赋值构成了一个序列点.因此,根据C90标准,必须在开始访问b之前完成对volatile变量a的访问.将这段代码翻译成x86-64汇编程序时,函数体将翻译如下:

movl $1, a(%rip)
movl $0, x(%rip)
movl $2, b(%rip)
Run Code Online (Sandbox Code Playgroud)

现在,当执行该代码时,CPU可以重新排序存储器访问,从而破坏了C标准的要求,即按顺序执行对a和b的访问.那么,这个翻译是不正确的,编译器是否不得不插入内存障碍来强制执行排序?

编辑:考虑a和b是由两个线程共享的变量的情况.在这种情况下,两个线程之间的同步协议可能依赖于对a和b的访问按顺序发生的事实.因此,当CPU重新排序访问时,这可能会破坏该协议(我实际上并没有尝试实现这样的协议,我只是想知道C标准的正确解释是什么).

cni*_*tar 6

CPU可能会重新排序指令,但他们必须确保结果与未执行相同.

  • @HermannSpeiche:如果你唯一的线程安全形式是使用`volatile`,那么即使没有CPU指令重新排序你也会遇到问题.您应该使用正确的线程同步机制. (2认同)
  • @OliCharlesworth:*"C标准没有线程概念"* - 现在就是这样.最近批准的ISO C11标准包括(可选)支持线程. (2认同)
  • @drhirsch:不,那是C.今年C和C++都有新的ISO标准.http://www.open-std.org/JTC1/SC22/WG14/,http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=57853 (2认同)