考虑这段代码,其中 x
和 y
是整数:
if (x)
y = 42;
是否允许以下编译器转换?
int tmp = y;
y = 42;
if (!x)
y = tmp;
上下文:
这是来自 Bjarne Stroustrup 的常见问题解答:
// start with x==0 and y==0
if (x) y = 1; // Thread 1
if (y) x = 1; // Thread 2
常见问题解答指出这是免费的数据竞争; x
和 y
均为 0,则不应写入任何变量。
但是如果允许转换呢?
最佳答案
与我在错误评论中所写的不同,如果 y
可能在线程之间共享并且编译器无法证明原始代码中存在任何现有 UB,则实际上不允许进行此转换。
标准明确指出:
Compiler transformations that introduce assignments to a potentially shared memory location that would not be modified by the abstract machine are generally precluded by this standard, since such an assignment might overwrite another assignment by a different thread in cases in which an abstract machine execution would not have encountered a data race.
N3337 中的 [intro.multithread] (1.10/22),N4141 中的 (1.10/25)。
因此,如果 x
始终为 0,则原始代码将是无竞争的,而转换后的代码则不会。因此转换是不合法的。
关于c++ - 是否允许此编译器转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45885048/