假设以下代码
struct a {
unsigned cntr;
};
void boo(struct a *v) {
v->cntr++;
while(v->cntr > 1);
}
由于 C11 标准中的以下语句,我想知道是否允许编译器省略 boo()
内的 while
循环:
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?
是的。
关于C11 - 编译器忽略潜在的无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70182416/