是否允许此编译器转换?

考虑这段代码,其中 xy 是整数:

if (x)
    y = 42;

是否允许以下编译器转换?

int tmp = y;
y = 42;

if (!x)
    y = tmp;

context

这是来自Bjarne Stroustrup的FAQ:

// start with x==0 and y==0

if (x) y = 1;   // Thread 1 

if (y) x = 1;   // Thread 2

常见问题解答说这是数据竞争免费;如果 xy 均为0,则不应写入任何变量 .
但如果允许转换怎么办?

回答(1)

2 years ago

与我在不正确的注释中写的不同,如果 y 可能在线程之间共享并且编译器无法证明原始代码中的任何现有UB,则实际上不允许此转换 .

该标准明确指出:

引入可能由抽象机器修改的潜在共享内存位置的编译器的编译器转换通常会被此标准排除,因为在抽象机器执行不会执行的情况下,这样的分配可能会覆盖另一个线程的另一个分配遇到了数据竞赛 .

N3337中的[intro.multithread](1.10 / 22),N4141中的(1.10 / 25) .

因此,如果 x 始终为0,则原始代码将无竞争,而转换后的代码则不会 . 因此,转型是不合法的 .