是否允许此编译器转换?

LWi*_*sey 9 c++ multithreading c++11 data-race

考虑这个代码,where xy是整数:

if (x)
    y = 42;
Run Code Online (Sandbox Code Playgroud)

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

int tmp = y;
y = 42;

if (!x)
    y = tmp;
Run Code Online (Sandbox Code Playgroud)

背景:

这是来自Bjarne Stroustrup的FAQ:

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

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

if (y) x = 1;   // Thread 2
Run Code Online (Sandbox Code Playgroud)

常见问题解答说这是数据竞争免费; 使用xy0都不应该写入任何变量.
但如果允许转换怎么办?

Bau*_*gen 7

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

该标准明确指出:

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

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

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

  • 特别是,与某个其他不正确的注释相反,as-if规则本身对单个线程没有任何限制.通过使数据竞争UB,该标准允许优化器假设数据竞争不会发生并相应地进行优化,这实际上使优化器能够在很大程度上将其分析限制为单个线程.但是,如果没有,那么实现引入数据竞争的权限就没有了. (3认同)