[英]C11 - omitting potentially infinite loop by the compiler
假設以下代碼
struct a {
unsigned cntr;
};
void boo(struct a *v) {
v->cntr++;
while(v->cntr > 1);
}
由於 C11 標准中的以下語句,我想知道是否允許編譯器省略boo()
中的while
循環:
控制表達式不是常量表達式的迭代語句, 156)不執行輸入/輸出操作,不訪問易失性對象,並且在其主體、控制表達式或(在 for 的情況下)不執行同步或原子操作statement) 其表達式 3,可被實現假定為終止。 157)
157)這旨在允許編譯器轉換,例如即使在無法證明終止時也可以刪除空循環。
v->cntr
在控制表達式中是否可以被視為同步,因為v
可能是指向可以在外部修改的全局結構的指針(例如由另一個線程)?
附加問題。 如果v
未定義為volatile
,是否允許編譯器在每次迭代時不重新讀取v->cntr
?
控制表達式中的 v->cntr 是否可以視為同步
不。
從https://port70.net/~nsz/c/c11/n1570.html#5.1.2.4p5 :
該庫定義了許多原子操作 (7.17) 和互斥鎖操作 (7.26.4),它們被特別標識為同步操作。
所以基本上, stdatomic.h 中的函數和stdatomic.h
中的thread.h
mtx_*
是同步操作。
因為 v 可能是指向可以在外部修改的全局結構的指針(例如由另一個線程)?
不要緊。 對我來說,假設聽起來就像它們不允許許多合理的優化一樣,我不希望我的編譯器假設這一點。
如果v
在另一個線程中被修改,那么它將是未排序的,這只會導致未定義的行為https://port70.net/~nsz/c/c11/n1570.html#5.1.2.4p25 。
如果 v 未定義為 volatile,是否允許編譯器在每次迭代時不重新讀取 v->cntr?
是的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.