質問するログイン新規登録

回答編集履歴

4

fix c

2018/08/29 02:54

投稿

yohhoy
yohhoy

スコア6191

answer CHANGED
@@ -39,7 +39,7 @@
39
39
  ```c
40
40
  // int型を含む集成体(struct)型は...
41
41
  struct S {
42
- double b
42
+ double b;
43
43
  int i;
44
44
  };
45
45
 
@@ -47,7 +47,7 @@
47
47
  // int型と互換性のある型(=int型自身を含む)のエイリアスになっている可能性があるため...
48
48
  *a = 0;
49
49
  // 下記の処理によりメモリ位置*aが書き換わる可能性がある
50
- S t = { 3.14, 42 };
50
+ struct S t = { 3.14, 42 };
51
51
  *s = t;
52
52
  // つまり下記処理では改めてメモリ位置*aから値を読み込まなければならない。
53
53
  printf("%d", *a);

3

fix

2018/08/29 02:54

投稿

yohhoy
yohhoy

スコア6191

answer CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  C言語仕様の"Strict Aliasing Rules"は、C言語プログラマのための規則ではなく、**C言語コンパイラ製作者のための規則**という側面が強いものです。
4
4
 
5
- "Strict Aliasing Rules"の本題は、Cコンパイラは「変数型が異なる場合は、互いにエイリアス(別名)となっている可能性を想定なく良く」、「エイリアス不在を仮定した生成コード最適化を行っ良い」というものです。"Strict(厳密な)"とは、コンパイラ視点からは「型に互換性がある場合は、互いにエイリアス(別名)の**可能性を考慮すべき**」、プログラマ視点からは「互換性のない型でエイリアスを**作ってはいけない**」というニュアンスから来ています。
5
+ "Strict Aliasing Rules"の本題は、Cコンパイラは「変数型が異なる場合は、互いにエイリアス(別名)となっている可能性を排除して良く」、「エイリアス不在を前提とした生成コード最適化をて良い」というものです。"Strict(厳密な)"とは、コンパイラ視点からは「型に互換性がある場合は、互いにエイリアス(別名)の**可能性を考慮すべき**」、プログラマ視点からは「互換性のない型でエイリアスを**作ってはいけない**」というニュアンスから来ています。
6
6
 
7
7
 
8
8
  > オブジェクトに格納された値に対するアクセスは,次のうちのいずれか1つの型を持つ左辺値によらなければならない。
9
9
  > (略)
10
10
 
11
- 上記5つのルールは、"Strict Aliasing Rules"の**例外事項**を規定しています。例えば5番目「文字型(a character type)」は、基本ルールでは`int`型と`char`型は互換性のない型なのでエイリアスになってはいけないが、例外規定により「エイリアスになり得ると考慮すべき(コンパイラ視点)」「エイリアスを作っても良い(プログラマ視点)」という意味です。
11
+ 上記5つのルールは、"Strict Aliasing Rules"の**例外事項**を規定しています。例えば5番目「文字型(a character type)」は、基本ルールに従うと`int`型と`char`型は互換性のない型なので互いにエイリアスであってはいけないが、例外規定により「エイリアスになり得ると考慮すべき(コンパイラ視点)」「エイリアスを作っても良い(プログラマ視点)」という意味です。
12
12
 
13
13
  ----
14
14
 
@@ -28,7 +28,6 @@
28
28
  ```
29
29
 
30
30
 
31
-
32
31
  > このうち、構造体・共用体の規則以外は理解できたのですが、4つ目の
33
32
  >
34
33
  > "メンバの中に上に列挙した型の1つを含む集成体型または共用体型(再帰的に包含されている部分集成体または含まれる共用体のメンバを含む)"
@@ -49,7 +48,7 @@
49
48
  *a = 0;
50
49
  // 下記の処理によりメモリ位置*aが書き換わる可能性がある
51
50
  S t = { 3.14, 42 };
52
- s = t;
51
+ *s = t;
53
52
  // つまり下記処理では改めてメモリ位置*aから値を読み込まなければならない。
54
53
  printf("%d", *a);
55
54
  }
@@ -62,4 +61,4 @@
62
61
 
63
62
  コンパイラが"Strict Aliasing Rules"をサポートするとは、前掲のように「型情報に基づいた積極的コード生成最適化を行う」という意味です。最新のVisualC++事情までは把握していませんが、私が知る限りはVisual C++はこのような積極的な**最適化を行いません**。なお、GCCやClangは積極的な最適化をサポートします。
64
63
 
65
- 善意的に解釈すればプログラマに優しく、悪意を持って解釈すれば性能が劣るコンパイラということになります。しかし、"Strict Aliasing Rules"を厳密に守っているプログラムはほとんど存在せず(たぶん)、積極的な最適化はしばしばトラブルの元になります。C言語仕様で規定する以上「Cコンパイラが正しくプログラムが誤っている」のですが、現実的には"Strict Aliasing Rules"に基づいた最適化を無効化して運用されることが多いようです。
64
+ 善意的に解釈すればプログラマに優しく、悪意を持って解釈すれば最適化性能が劣るコンパイラということになります。しかし、"Strict Aliasing Rules"を厳密に守っているプログラムはほとんど存在せず(たぶん)、積極的な最適化はしばしばトラブルの元になります。C言語仕様で規定する以上「Cコンパイラが正しくプログラムが誤っている」のですが、現実的には"Strict Aliasing Rules"に基づいた最適化を無効化して運用されることが多いようです。GCC、Clangでは`-fno-strict-aliasing`オプションが用いられます。

2

refine

2018/08/29 02:09

投稿

yohhoy
yohhoy

スコア6191

answer CHANGED
@@ -38,7 +38,7 @@
38
38
  この例外規則の解釈は、下記の通りです。プログラマ視点では当然のことを言っているように見えるかもしれまん。
39
39
 
40
40
  ```c
41
- // int型を含む集成体型は...
41
+ // int型を含む集成体(struct)型は...
42
42
  struct S {
43
43
  double b
44
44
  int i;
@@ -47,8 +47,9 @@
47
47
  void g(struct S* s, int* a) {
48
48
  // int型と互換性のある型(=int型自身を含む)のエイリアスになっている可能性があるため...
49
49
  *a = 0;
50
- // 下記の処理*a書き換わる可能性がある...
50
+ // 下記の処理によりメモリ位置*a書き換わる可能性がある
51
+ S t = { 3.14, 42 };
51
- s->i = 42;
52
+ s = t;
52
53
  // つまり下記処理では改めてメモリ位置*aから値を読み込まなければならない。
53
54
  printf("%d", *a);
54
55
  }

1

update

2018/08/28 17:00

投稿

yohhoy
yohhoy

スコア6191

answer CHANGED
@@ -23,7 +23,7 @@
23
23
  // つまり下記処理で改めてメモリ位置*aから値を読み込む必要はなく、
24
24
  // 最適化によって "前掲処理で代入した直値0" をそのまま使って良い。
25
25
  printf("%d", *a);
26
- // つまり↑をprintf("%d", 0);やprintf("0");に最適化しても良い。
26
+ // コンパイラは↑をprintf("%d", 0);やprintf("0");に最適化しても良い。
27
27
  }
28
28
  ```
29
29
 
@@ -52,4 +52,13 @@
52
52
  // つまり下記処理では改めてメモリ位置*aから値を読み込まなければならない。
53
53
  printf("%d", *a);
54
54
  }
55
- ```
55
+ ```
56
+
57
+ ----
58
+
59
+ > visual studio C++ が strict aliasing rules をサポートしているのかについて調査をしてみたのですが、そのようなものは見つかりませんでした。
60
+ > もしかしたらそもそもサポートしていないのではないのかと思いました。
61
+
62
+ コンパイラが"Strict Aliasing Rules"をサポートするとは、前掲のように「型情報に基づいた積極的コード生成最適化を行う」という意味です。最新のVisualC++事情までは把握していませんが、私が知る限りはVisual C++はこのような積極的な**最適化を行いません**。なお、GCCやClangは積極的な最適化をサポートします。
63
+
64
+ 善意的に解釈すればプログラマに優しく、悪意を持って解釈すれば性能が劣るコンパイラということになります。しかし、"Strict Aliasing Rules"を厳密に守っているプログラムはほとんど存在せず(たぶん)、積極的な最適化はしばしばトラブルの元になります。C言語仕様で規定する以上「Cコンパイラが正しくプログラムが誤っている」のですが、現実的には"Strict Aliasing Rules"に基づいた最適化を無効化して運用されることが多いようです。