C11 - 编译器省略了潜在的无限循环

C11 - omitting potentially infinite loop by the compiler

假设以下代码

struct a {
    unsigned cntr;
};

void boo(struct a *v) {
    v->cntr++;
    while(v->cntr > 1);
}

我想知道是否允许编译器省略 boo() 中的 while 循环,因为 C11 标准中有以下语句:

An iteration statement whose controlling expression is not a constant expression,156) that performs no input/output operations, does not access volatile objects, and performs no synchronization or atomic operations in its body, controlling expression, or (in the case of a for statement) its expression-3, may be assumed by the implementation to terminate.157)


157)This is intended to allow compiler transformations such as removal of empty loops even when termination cannot be proven.

可以在控制表达式中将 v->cntr 视为 同步 因为 v 可能是指向可以修改的全局结构的指针外部(例如通过另一个线程)?

补充问题。 如果 v 未定义为 volatile,是否允许编译器在每次迭代时不重新读取 v->cntr

Can v->cntr, in the controlling expression, be considered as a synchronization

没有

来自 https://port70.net/~nsz/c/c11/n1570.html#5.1.2.4p5 :

The library defines a number of atomic operations (7.17) and operations on mutexes (7.26.4) that are specially identified as synchronization operations.

所以基本上,stdatomic.h 中的函数和 thread.h 中的 mtx_* 中的函数都是同步操作。

since v may be a pointer to a global structure which can be modified externally (for example by another thread)?

无所谓。假设对我来说听起来像是不允许许多理智的优化,我不希望我的编译器假设那样。

如果 v 在另一个线程中被修改,那么它将是无序的,这只会导致未定义的行为 https://port70.net/~nsz/c/c11/n1570.html#5.1.2.4p25 .

Is the compiler allowed not to re-read v->cntr on each iteration if v is not defined as volatile?

是的。