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

标签 c compiler-construction assembly standards

考虑以下代码:

volatile int a;
volatile int b;
int x;

void func() {
    a = 1;
    x = 0; /* dummy statement */
    b = 2;
}

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

movl $1, a(%rip)
movl $0, x(%rip)
movl $2, b(%rip)

现在,当执行这段代码时,CPU 可能会对内存访问重新排序,从而打破了 C 标准对 a 和 b 的访问按顺序执行的要求。那么,这种翻译是不是不正确,编译器是否必须插入内存屏障来强制执行排序?

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

最佳答案

CPU 可能会对指令重新排序,但它们必须确保结果与没有重新排序的结果相同

关于c - 兼容 C90 的编译器是否必须考虑 CPU 的指令重新排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8639086/

相关文章:

linux - 了解汇编代码

assembly - 在 ASM 中调用 windows 函数(推送/弹出问题)

具有非确定性输出的 C fork and pipe 程序

c++ - 使用符号构建字符串

C 编译器可以围绕调用预取数据吗?

c# - Visual Studio编译时跳过某些错误

c++ - 如何改进编译器对我的 SSE 内在函数的处理?

c - 系统调用未定义!编译内核模块

c - 带有 "%d"以 0 开头的数字(例如 "0102")的 printf 给出意外的答案(例如 '"66")

为两台不同机器创建目标代码的 C++ 编译器