a=aは未定義動作になりうるか?
はじめに
注意
この記事は僕がC11の規格を独自に解釈したものであり,この記事の正当性を何ら保証するものではありません.
この記事を吹聴して恥をかいても,自己責任でおねがいします.
寧ろツッコミ大歓迎です.
知っておくと良いこと(前提知識ではないので知らなくても良い)
主張
式文 a=a
は未定義動作になりうる.
条件
変数(オブジェクト)a
がvolatile
修飾子付きで宣言されている.
例えば,
int main(void) {
volatile int a = 0;
a = a;
}
など
この時,全てのa
に対するアクセスは6.7.3 paragraph 7によって処理系定義であることに注意すべき.
なぜ未定義動作になるか
- 5.1.2.3 paragraph 2より,volatile objectへのアクセスはside effect,即ち副作用を生む.
- 6.5.16 paragraph 3より,左辺値への代入は副作用を含み,その副作用は右のオペランドと左のオペランドを評価したあとに行われ,左右のオペランドの評価の順序はunsequencedである(定義されない?でいいのか).
- 6.5 paragraph 2によって,あるオブジェクトに対する副作用が同じオブジェクトの別の副作用と関係していて,それらの副作用の順序が定義されていない時,未定義動作である.
-
- より,
a=a
は右辺を評価した時にa
に副作用が生じ,
単純代入の式なので,a
をa
にするという副作用が生じる.
また,これらの副作用の順序は定義されず,副作用完了点までに副作用が生じていれば良い.
よって,3. の条件を満たすため,a=a
は未定義動作となる.
- より,
結論
以上により,a=a
は未定義動作になりうる.