回答編集履歴

8

回答の編集

2020/04/12 09:17

投稿

alphya
alphya

スコア124

test CHANGED
@@ -134,7 +134,7 @@
134
134
 
135
135
 
136
136
 
137
- (d): [basic.life]/7.1 より、「オブジェクトにアクセスするために glvalue が使用される」ため、UB
137
+ (d): ~~ [basic.life]/7.1 より、「オブジェクトにアクセスするために glvalue が使用される」ため、UB ~~ lifetime が終了したオブジェクトへのアクセスではないため、UB ではありません(コメント欄参照)
138
138
 
139
139
 
140
140
 

7

回答の編集

2020/04/12 09:17

投稿

alphya
alphya

スコア124

test CHANGED
@@ -92,7 +92,7 @@
92
92
 
93
93
 
94
94
 
95
- また、このような解釈では、例示された (c), (d), (e), (f) の操作は、未定義動作となる条件である [basic.life]/6.1 から 6.5 に該当しないためどれも適格な操作だと考えられます。ただし、(a), (b) は strict aliasing rule によって未定義動作だと考えられます。(@onihusube9 on Twitter さんにご指摘をいただきました。ありがとうございます。)
95
+ また、このような解釈では、例示された (c), (d), (e), (f) の操作は、未定義動作となる条件である [basic.life]/6.1 から 6.5 に該当しないためどれも適格な操作だと考えられます。ただし、(a), (b) は strict aliasing rule によって未定義動作だと考えられます。
96
96
 
97
97
 
98
98
 

6

追記

2020/04/11 03:25

投稿

alphya
alphya

スコア124

test CHANGED
@@ -92,4 +92,54 @@
92
92
 
93
93
 
94
94
 
95
- また、このような解釈では、例示された (c), (d), (e), (f) の操作は、未定義動作となる条件である [basic.life]/6.1 から 6.5 に該当しないためどれも適格な操作だと考えられます。ただし、(a), (b) は strict aliasing rule によって未定義動作だと考えられます。
95
+ また、このような解釈では、例示された (c), (d), (e), (f) の操作は、未定義動作となる条件である [basic.life]/6.1 から 6.5 に該当しないためどれも適格な操作だと考えられます。ただし、(a), (b) は strict aliasing rule によって未定義動作だと考えられます。(@onihusube9 on Twitter さんにご指摘をいただきました。ありがとうございます。)
96
+
97
+
98
+
99
+ ---
100
+
101
+ [追記 2]
102
+
103
+
104
+
105
+ ISO C++ Standard - Discussion へこの質問を送り、回答をいただきました:
106
+
107
+ https://lists.isocpp.org/std-discussion/2020/04/0511.php
108
+
109
+
110
+
111
+ この回答によれば、[basic.life]/6 の記述は「あるオブジェクトの生存期間(lifetime)が終了したあとに、同オブジェクトが占めていたストレージ上にオブジェクトが生成されている、その同ストレージへのポインタ」にも適用されるようです。
112
+
113
+
114
+
115
+ また、例示された操作については次のようになるようです。
116
+
117
+
118
+
119
+ (a): UB ではありません。なぜなら:
120
+
121
+ [basic.lval]/1.4 "lvalue は、xvalue でない glvalue です"
122
+
123
+ [basic.life]/6 "そのようなポインターを介した間接指定は許可されますが、結果の lvalue は、以下で説明するように、限られた方法でのみ使用できます"
124
+
125
+ [basic.life]/7 "その値に依存しない glvalue のプロパティの使用は well-defined です"
126
+
127
+
128
+
129
+ (b): 式 *p32 + 100 は、「その値に依存する glvalue のプロパティを使用している」ため UB
130
+
131
+
132
+
133
+ (c): p32 は有効なポインタであるため、これは問題ありません
134
+
135
+
136
+
137
+ (d): [basic.life]/7.1 より、「オブジェクトにアクセスするために glvalue が使用される」ため、UB
138
+
139
+
140
+
141
+ (e): この時点で、タイプ std::uint16_t の 4 つのオブジェクトは、ストレージの再利用のために lifetime が終了しています。ただし、std::uint32_t タイプの 4 つのオブジェクトは、 `{}` がないために作成されていません
142
+
143
+
144
+
145
+ (f): これにより、ストレージの割り当てが解除されます。std::uint32_t は no non-trivial destructor をもつため UB ではありません

5

書式の改善

2020/04/11 02:49

投稿

alphya
alphya

スコア124

test CHANGED
@@ -84,7 +84,7 @@
84
84
 
85
85
 
86
86
 
87
- nus_miz さんのご指摘のように、[basic.life]/6 の記述は一見すると「あるオブジェクト#1の生存期間(lifetime)が終了したあとに、同オブジェクト#1が占めていたストレージ上にオブジェクト#2が生成されていない、その同ストレージへのポインタ」に関する記述だと読めるが、"Indirection through such a..." からの文を含めた "Otherwise" 節以降の文は「あるオブジェクトの生存期間(lifetime)が終了したあとに、同オブジェクトが占めていたストレージ上にオブジェクトが生成されている、その同ストレージへのポインタ」にも適用される、という解釈だと、付随する Example がこの位置にあることや、`*pb` の間接参照が適格だということに説明が付きそうです。
87
+ nus_miz さんのご指摘のように、[basic.life]/6 の記述は一見すると「あるオブジェクトの生存期間(lifetime)が終了したあとに、同オブジェクトが占めていたストレージ上にオブジェクトが生成されていない、その同ストレージへのポインタ」に関する記述だと読めるが、"Indirection through such a..." からの文を含めた "Otherwise" 節以降の文は「あるオブジェクトの生存期間(lifetime)が終了したあとに、同オブジェクトが占めていたストレージ上にオブジェクトが生成されている、その同ストレージへのポインタ」にも適用される、という解釈だと、付随する Example がこの位置にあることや、`*pb` の間接参照が適格だということに説明が付きそうです。
88
88
 
89
89
 
90
90
 

4

用語の修正

2020/04/10 08:21

投稿

alphya
alphya

スコア124

test CHANGED
@@ -1,3 +1,7 @@
1
+ [4/10 17:18 yohhoy さんの回答より、用語の使い方を修正しました]
2
+
3
+
4
+
1
5
  > lifetime が終了し、かつ storage が他のオブジェクトによって再利用されたオブジェクトを指しているポインタに対して、規格上どのような操作が許されるのか
2
6
 
3
7
 
@@ -44,7 +48,7 @@
44
48
 
45
49
 
46
50
 
47
- が「lifetime が終了し、かつ storage 再利用されていオブジェクト」を指すポインタにも適用されるように読み取れます。
51
+ が「あるオブジェクトの生存期間(lifetime)が終了したあとに同オブジェクト占めていたストレージ上にオブジェクトが生成されている、その同ストレージへのポインタにも適用されるように読み取れます。
48
52
 
49
53
 
50
54
 
@@ -52,7 +56,7 @@
52
56
 
53
57
 
54
58
 
55
- (個人的には [basic.life]/6 は「lifetime終了その storage 解放まは再利用されていないオブェクト」を指すポインタに関する記述となるようにも読めると思います...)
59
+ (個人的には [basic.life]/6 は「あるオブジェクトの生存期間(lifetime)が終了したあとに同オブジェクト#1占めていストレージ上にオブジェクトが生成されていない、その同ストレーへのポインタに関する記述となるようにも読めると思います...)
56
60
 
57
61
 
58
62
 
@@ -60,7 +64,7 @@
60
64
 
61
65
 
62
66
 
63
- ここでは、上記の StackOverflow の回答の解釈([basic.life]/6 の "Otherwise" 節の記述が「lifetime が終了し、かつ storage 再利用されていオブジェクト」を指すポインタにも適用される)に従って回答します。
67
+ ここでは、上記の StackOverflow の回答の解釈([basic.life]/6 の "Otherwise" 節の記述が「あるオブジェクトの生存期間(lifetime)が終了したあとに同オブジェクト占めていたストレージ上にオブジェクトが生成されている、その同ストレージへのポインタにも適用される)に従って回答します。
64
68
 
65
69
 
66
70
 
@@ -80,7 +84,7 @@
80
84
 
81
85
 
82
86
 
83
- nus_miz さんのご指摘のように、[basic.life]/6 の記述は一見すると「lifetime終了その storage 解放まは再利用されていないオブェクト」を指すポインタに関する記述だと読めるが、"Indirection through such a..." からの文を含めた "Otherwise" 節以降の文は「lifetime が終了し、かつ storage 再利用されていオブジェクト」を指すポインタにも適用される、という解釈だと、付随する Example がこの位置にあることや、`*pb` の間接参照が適格だということに説明が付きそうです。
87
+ nus_miz さんのご指摘のように、[basic.life]/6 の記述は一見すると「あるオブジェクト#1の生存期間(lifetime)が終了したあとに同オブジェクト#1占めていストレージ上にオブジェクト#2が生成されていない、その同ストレーへのポインタに関する記述だと読めるが、"Indirection through such a..." からの文を含めた "Otherwise" 節以降の文は「あるオブジェクトの生存期間(lifetime)が終了したあとに同オブジェクト占めていたストレージ上にオブジェクトが生成されている、その同ストレージへのポインタにも適用される、という解釈だと、付随する Example がこの位置にあることや、`*pb` の間接参照が適格だということに説明が付きそうです。
84
88
 
85
89
 
86
90
 

3

文面の修正

2020/04/10 08:19

投稿

alphya
alphya

スコア124

test CHANGED
@@ -88,4 +88,4 @@
88
88
 
89
89
 
90
90
 
91
- また、このような解釈では、例示された (c), (d), (e), (f) の操作は、未定義動作となる条件である [basic.life]/6.1 から 6.5 に該当しないためどれも適格な操作だと考えられます。ただし、(a), (b) は strict aliasing rule に反するので未定義動作だと考えられます。
91
+ また、このような解釈では、例示された (c), (d), (e), (f) の操作は、未定義動作となる条件である [basic.life]/6.1 から 6.5 に該当しないためどれも適格な操作だと考えられます。ただし、(a), (b) は strict aliasing rule によって未定義動作だと考えられます。

2

追記の変更

2020/04/10 08:07

投稿

alphya
alphya

スコア124

test CHANGED
@@ -88,4 +88,4 @@
88
88
 
89
89
 
90
90
 
91
- また、このような解釈では、例示された (a) から (f) の操作は、未定義動作となる条件である [basic.life]/6.1 から 6.5 に該当しないためどれも適格な操作だと考えられます。
91
+ また、このような解釈では、例示された (c), (d), (e), (f) の操作は、未定義動作となる条件である [basic.life]/6.1 から 6.5 に該当しないためどれも適格な操作だと考えられます。ただし、(a), (b) は strict aliasing rule に反するので未定義動作だと考えられます。

1

追記

2020/04/10 08:05

投稿

alphya
alphya

スコア124

test CHANGED
@@ -71,3 +71,21 @@
71
71
  (d): (a), (b) と同じ理由により Undefined Behavior
72
72
 
73
73
  (e), (f): [basic.life]/8 の条件を満たすので適格
74
+
75
+
76
+
77
+ ---
78
+
79
+ [追記]
80
+
81
+
82
+
83
+ nus_miz さんのご指摘のように、[basic.life]/6 の記述は一見すると「lifetime の終了後、その storage が解放または再利用されていないオブジェクト」を指すポインタに関する記述だと読めるが、"Indirection through such a..." からの文を含めた "Otherwise" 節以降の文は「lifetime が終了し、かつ storage が再利用されているオブジェクト」を指すポインタにも適用される、という解釈だと、付随する Example がこの位置にあることや、`*pb` の間接参照が適格だということに説明が付きそうです。
84
+
85
+
86
+
87
+ "Indirection" からの文が適用されないという解釈の根拠は cppreference の記事でしたが、このサイトも C++ の公式のものだというわけではないので、上記のような規格の記述に一貫性のある解釈の方が妥当だと思います。
88
+
89
+
90
+
91
+ また、このような解釈では、例示された (a) から (f) の操作は、未定義動作となる条件である [basic.life]/6.1 から 6.5 に該当しないためどれも適格な操作だと考えられます。