From Jason Turner

[intro.races]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmptbom234c/{from.md → to.md} +137 -134
tmp/tmptbom234c/{from.md → to.md} RENAMED
@@ -1,66 +1,62 @@
1
- ### Data races <a id="intro.races">[[intro.races]]</a>
2
 
3
- The value of an object visible to a thread *T* at a particular point is
4
- the initial value of the object, a value assigned to the object by *T*,
5
- or a value assigned to the object by another thread, according to the
6
- rules below.
7
 
8
  [*Note 1*: In some cases, there may instead be undefined behavior. Much
9
- of this section is motivated by the desire to support atomic operations
10
- with explicit and detailed visibility constraints. However, it also
11
- implicitly supports a simpler view for more restricted
12
  programs. — *end note*]
13
 
14
  Two expression evaluations *conflict* if one of them modifies a memory
15
- location ([[intro.memory]]) and the other one reads or modifies the
16
- same memory location.
17
 
18
- The library defines a number of atomic operations (Clause  [[atomics]])
19
- and operations on mutexes (Clause  [[thread]]) that are specially
20
- identified as synchronization operations. These operations play a
21
- special role in making assignments in one thread visible to another. A
22
- synchronization operation on one or more memory locations is either a
23
- consume operation, an acquire operation, a release operation, or both an
24
- acquire and release operation. A synchronization operation without an
25
- associated memory location is a fence and can be either an acquire
26
- fence, a release fence, or both an acquire and release fence. In
27
- addition, there are relaxed atomic operations, which are not
28
- synchronization operations, and atomic read-modify-write operations,
29
- which have special characteristics.
30
 
31
  [*Note 2*: For example, a call that acquires a mutex will perform an
32
  acquire operation on the locations comprising the mutex.
33
  Correspondingly, a call that releases the same mutex will perform a
34
  release operation on those same locations. Informally, performing a
35
- release operation on *A* forces prior side effects on other memory
36
  locations to become visible to other threads that later perform a
37
- consume or an acquire operation on *A*. “Relaxed” atomic operations are
38
  not synchronization operations even though, like synchronization
39
  operations, they cannot contribute to data races. — *end note*]
40
 
41
- All modifications to a particular atomic object *M* occur in some
42
- particular total order, called the *modification order* of *M*.
43
 
44
  [*Note 3*: There is a separate order for each atomic object. There is
45
  no requirement that these can be combined into a single total order for
46
  all objects. In general this will be impossible since different threads
47
  may observe modifications to different objects in inconsistent
48
  orders. — *end note*]
49
 
50
- A *release sequence* headed by a release operation *A* on an atomic
51
- object *M* is a maximal contiguous sub-sequence of side effects in the
52
- modification order of *M*, where the first operation is `A`, and every
53
- subsequent operation
54
-
55
- - is performed by the same thread that performed `A`, or
56
- - is an atomic read-modify-write operation.
57
 
58
  Certain library calls *synchronize with* other library calls performed
59
  by another thread. For example, an atomic store-release synchronizes
60
- with a load-acquire that takes its value from the store (
61
- [[atomics.order]]).
62
 
63
  [*Note 4*: Except in the specified cases, reading a later value does
64
  not necessarily ensure visibility as described below. Such a requirement
65
  would sometimes interfere with efficient implementation. — *end note*]
66
 
@@ -68,55 +64,52 @@ would sometimes interfere with efficient implementation. — *end note*]
68
  when one reads the value written by another. For atomic objects, the
69
  definition is clear. All operations on a given mutex occur in a single
70
  total order. Each mutex acquisition “reads the value written” by the
71
  last mutex release. — *end note*]
72
 
73
- An evaluation *A* *carries a dependency* to an evaluation *B* if
74
 
75
- - the value of *A* is used as an operand of *B*, unless:
76
- - *B* is an invocation of any specialization of
77
- `std::kill_dependency` ([[atomics.order]]), or
78
- - *A* is the left operand of a built-in logical AND (`&&`, see 
79
- [[expr.log.and]]) or logical OR (`||`, see  [[expr.log.or]])
80
- operator, or
81
- - *A* is the left operand of a conditional (`?:`, see  [[expr.cond]])
82
  operator, or
83
- - *A* is the left operand of the built-in comma (`,`) operator (
84
- [[expr.comma]]);
85
 
86
  or
87
- - *A* writes a scalar object or bit-field *M*, *B* reads the value
88
- written by *A* from *M*, and *A* is sequenced before *B*, or
89
- - for some evaluation *X*, *A* carries a dependency to *X*, and *X*
90
- carries a dependency to *B*.
91
 
92
  [*Note 6*: “Carries a dependency to” is a subset of “is sequenced
93
  before”, and is similarly strictly intra-thread. — *end note*]
94
 
95
- An evaluation *A* is *dependency-ordered before* an evaluation *B* if
96
 
97
- - *A* performs a release operation on an atomic object *M*, and, in
98
- another thread, *B* performs a consume operation on *M* and reads a
99
- value written by any side effect in the release sequence headed by
100
- *A*, or
101
- - for some evaluation *X*, *A* is dependency-ordered before *X* and *X*
102
- carries a dependency to *B*.
103
 
104
  [*Note 7*: The relation “is dependency-ordered before” is analogous to
105
  “synchronizes with”, but uses release/consume in place of
106
  release/acquire. — *end note*]
107
 
108
- An evaluation *A* *inter-thread happens before* an evaluation *B* if
109
 
110
- - *A* synchronizes with *B*, or
111
- - *A* is dependency-ordered before *B*, or
112
- - for some evaluation *X*
113
- - *A* synchronizes with *X* and *X* is sequenced before *B*, or
114
- - *A* is sequenced before *X* and *X* inter-thread happens before *B*,
115
- or
116
- - *A* inter-thread happens before *X* and *X* inter-thread happens
117
- before *B*.
118
 
119
  [*Note 8*: The “inter-thread happens before” relation describes
120
  arbitrary concatenations of “sequenced before”, “synchronizes with” and
121
  “dependency-ordered before” relationships, with two exceptions. The
122
  first exception is that a concatenation is not permitted to end with
@@ -131,101 +124,111 @@ exception is that a concatenation is not permitted to consist entirely
131
  of “sequenced before”. The reasons for this limitation are (1) to permit
132
  “inter-thread happens before” to be transitively closed and (2) the
133
  “happens before” relation, defined below, provides for relationships
134
  consisting entirely of “sequenced before”. — *end note*]
135
 
136
- An evaluation *A* *happens before* an evaluation *B* (or, equivalently,
137
- *B* *happens after* *A*) if:
138
 
139
- - *A* is sequenced before *B*, or
140
- - *A* inter-thread happens before *B*.
141
 
142
  The implementation shall ensure that no program execution demonstrates a
143
  cycle in the “happens before” relation.
144
 
145
  [*Note 9*: This cycle would otherwise be possible only through the use
146
  of consume operations. — *end note*]
147
 
148
- An evaluation *A* *strongly happens before* an evaluation *B* if either
149
 
150
- - *A* is sequenced before *B*, or
151
- - *A* synchronizes with *B*, or
152
- - *A* strongly happens before *X* and *X* strongly happens before *B*.
153
 
154
  [*Note 10*: In the absence of consume operations, the happens before
155
- and strongly happens before relations are identical. Strongly happens
156
- before essentially excludes consume operations. — *end note*]
157
 
158
- A *visible side effect* *A* on a scalar object or bit-field *M* with
159
- respect to a value computation *B* of *M* satisfies the conditions:
160
 
161
- - *A* happens before *B* and
162
- - there is no other side effect *X* to *M* such that *A* happens before
163
- *X* and *X* happens before *B*.
 
 
 
 
164
 
165
- The value of a non-atomic scalar object or bit-field *M*, as determined
166
- by evaluation *B*, shall be the value stored by the visible side effect
167
- *A*.
168
 
169
- [*Note 11*: If there is ambiguity about which side effect to a
 
 
 
 
 
 
 
 
 
 
170
  non-atomic object or bit-field is visible, then the behavior is either
171
  unspecified or undefined. — *end note*]
172
 
173
- [*Note 12*: This states that operations on ordinary objects are not
174
  visibly reordered. This is not actually detectable without data races,
175
  but it is necessary to ensure that data races, as defined below, and
176
  with suitable restrictions on the use of atomics, correspond to data
177
  races in a simple interleaved (sequentially consistent)
178
  execution. — *end note*]
179
 
180
- The value of an atomic object *M*, as determined by evaluation *B*,
181
- shall be the value stored by some side effect *A* that modifies *M*,
182
- where *B* does not happen before *A*.
183
 
184
- [*Note 13*: The set of such side effects is also restricted by the rest
185
  of the rules described here, and in particular, by the coherence
186
  requirements below. — *end note*]
187
 
188
- If an operation *A* that modifies an atomic object *M* happens before an
189
- operation *B* that modifies *M*, then *A* shall be earlier than *B* in
190
- the modification order of *M*.
191
 
192
- [*Note 14*: This requirement is known as write-write
193
  coherence. — *end note*]
194
 
195
- If a value computation *A* of an atomic object *M* happens before a
196
- value computation *B* of *M*, and *A* takes its value from a side effect
197
- *X* on *M*, then the value computed by *B* shall either be the value
198
- stored by *X* or the value stored by a side effect *Y* on *M*, where *Y*
199
- follows *X* in the modification order of *M*.
200
 
201
- [*Note 15*: This requirement is known as read-read
202
  coherence. — *end note*]
203
 
204
- If a value computation *A* of an atomic object *M* happens before an
205
- operation *B* that modifies *M*, then *A* shall take its value from a
206
- side effect *X* on *M*, where *X* precedes *B* in the modification order
207
- of *M*.
208
 
209
- [*Note 16*: This requirement is known as read-write
210
  coherence. — *end note*]
211
 
212
- If a side effect *X* on an atomic object *M* happens before a value
213
- computation *B* of *M*, then the evaluation *B* shall take its value
214
- from *X* or from a side effect *Y* that follows *X* in the modification
215
- order of *M*.
216
 
217
- [*Note 17*: This requirement is known as write-read
218
  coherence. — *end note*]
219
 
220
- [*Note 18*: The four preceding coherence requirements effectively
221
  disallow compiler reordering of atomic operations to a single object,
222
  even if both operations are relaxed loads. This effectively makes the
223
- cache coherence guarantee provided by most hardware available to
224
- C++atomic operations. — *end note*]
225
 
226
- [*Note 19*: The value observed by a load of an atomic depends on the
227
  “happens before” relation, which depends on the values observed by loads
228
  of atomics. The intended reading is that there must exist an association
229
  of atomic loads with modifications they observe that, together with
230
  suitably chosen modification orders and the “happens before” relation
231
  derived as described above, satisfy the resulting constraints as imposed
@@ -241,12 +244,12 @@ The execution of a program contains a *data race* if it contains two
241
  potentially concurrent conflicting actions, at least one of which is not
242
  atomic, and neither happens before the other, except for the special
243
  case for signal handlers described below. Any such data race results in
244
  undefined behavior.
245
 
246
- [*Note 20*: It can be shown that programs that correctly use mutexes
247
- and `memory_order_seq_cst` operations to prevent all data races and use
248
  no other synchronization operations behave as if the operations executed
249
  by their constituent threads were simply interleaved, with each value
250
  computation of an object being taken from the last side effect on that
251
  object in that interleaving. This is normally referred to as “sequential
252
  consistency”. However, this applies only to data-race-free programs, and
@@ -258,32 +261,32 @@ undefined operation. — *end note*]
258
 
259
  Two accesses to the same object of type `volatile std::sig_atomic_t` do
260
  not result in a data race if both occur in the same thread, even if one
261
  or more occurs in a signal handler. For each signal handler invocation,
262
  evaluations performed by the thread invoking a signal handler can be
263
- divided into two groups *A* and *B*, such that no evaluations in *B*
264
- happen before evaluations in *A*, and the evaluations of such
265
  `volatile std::sig_atomic_t` objects take values as though all
266
- evaluations in *A* happened before the execution of the signal handler
267
- and the execution of the signal handler happened before all evaluations
268
- in *B*.
269
 
270
- [*Note 21*: Compiler transformations that introduce assignments to a
271
  potentially shared memory location that would not be modified by the
272
- abstract machine are generally precluded by this International Standard,
273
- since such an assignment might overwrite another assignment by a
274
- different thread in cases in which an abstract machine execution would
275
- not have encountered a data race. This includes implementations of data
276
- member assignment that overwrite adjacent members in separate memory
277
- locations. Reordering of atomic loads in cases in which the atomics in
278
- question may alias is also generally precluded, since this may violate
279
- the coherence rules. — *end note*]
280
 
281
- [*Note 22*: Transformations that introduce a speculative read of a
282
  potentially shared memory location may not preserve the semantics of the
283
- C++program as defined in this International Standard, since they
284
- potentially introduce a data race. However, they are typically valid in
285
- the context of an optimizing compiler that targets a specific machine
286
- with well-defined semantics for data races. They would be invalid for a
287
  hypothetical machine that is not tolerant of races or provides hardware
288
  race detection. — *end note*]
289
 
 
1
+ #### Data races <a id="intro.races">[[intro.races]]</a>
2
 
3
+ The value of an object visible to a thread T at a particular point is
4
+ the initial value of the object, a value assigned to the object by T, or
5
+ a value assigned to the object by another thread, according to the rules
6
+ below.
7
 
8
  [*Note 1*: In some cases, there may instead be undefined behavior. Much
9
+ of this subclause is motivated by the desire to support atomic
10
+ operations with explicit and detailed visibility constraints. However,
11
+ it also implicitly supports a simpler view for more restricted
12
  programs. — *end note*]
13
 
14
  Two expression evaluations *conflict* if one of them modifies a memory
15
+ location [[intro.memory]] and the other one reads or modifies the same
16
+ memory location.
17
 
18
+ The library defines a number of atomic operations [[atomics]] and
19
+ operations on mutexes [[thread]] that are specially identified as
20
+ synchronization operations. These operations play a special role in
21
+ making assignments in one thread visible to another. A synchronization
22
+ operation on one or more memory locations is either a consume operation,
23
+ an acquire operation, a release operation, or both an acquire and
24
+ release operation. A synchronization operation without an associated
25
+ memory location is a fence and can be either an acquire fence, a release
26
+ fence, or both an acquire and release fence. In addition, there are
27
+ relaxed atomic operations, which are not synchronization operations, and
28
+ atomic read-modify-write operations, which have special characteristics.
 
29
 
30
  [*Note 2*: For example, a call that acquires a mutex will perform an
31
  acquire operation on the locations comprising the mutex.
32
  Correspondingly, a call that releases the same mutex will perform a
33
  release operation on those same locations. Informally, performing a
34
+ release operation on A forces prior side effects on other memory
35
  locations to become visible to other threads that later perform a
36
+ consume or an acquire operation on A. “Relaxed” atomic operations are
37
  not synchronization operations even though, like synchronization
38
  operations, they cannot contribute to data races. — *end note*]
39
 
40
+ All modifications to a particular atomic object M occur in some
41
+ particular total order, called the *modification order* of M.
42
 
43
  [*Note 3*: There is a separate order for each atomic object. There is
44
  no requirement that these can be combined into a single total order for
45
  all objects. In general this will be impossible since different threads
46
  may observe modifications to different objects in inconsistent
47
  orders. — *end note*]
48
 
49
+ A *release sequence* headed by a release operation A on an atomic object
50
+ M is a maximal contiguous sub-sequence of side effects in the
51
+ modification order of M, where the first operation is A, and every
52
+ subsequent operation is an atomic read-modify-write operation.
 
 
 
53
 
54
  Certain library calls *synchronize with* other library calls performed
55
  by another thread. For example, an atomic store-release synchronizes
56
+ with a load-acquire that takes its value from the store
57
+ [[atomics.order]].
58
 
59
  [*Note 4*: Except in the specified cases, reading a later value does
60
  not necessarily ensure visibility as described below. Such a requirement
61
  would sometimes interfere with efficient implementation. — *end note*]
62
 
 
64
  when one reads the value written by another. For atomic objects, the
65
  definition is clear. All operations on a given mutex occur in a single
66
  total order. Each mutex acquisition “reads the value written” by the
67
  last mutex release. — *end note*]
68
 
69
+ An evaluation A *carries a dependency* to an evaluation B if
70
 
71
+ - the value of A is used as an operand of B, unless:
72
+ - B is an invocation of any specialization of `std::kill_dependency`
73
+ [[atomics.order]], or
74
+ - A is the left operand of a built-in logical (`&&`, see 
75
+ [[expr.log.and]]) or logical (`||`, see  [[expr.log.or]]) operator,
76
+ or
77
+ - A is the left operand of a conditional (`?:`, see  [[expr.cond]])
78
  operator, or
79
+ - A is the left operand of the built-in comma (`,`) operator
80
+ [[expr.comma]];
81
 
82
  or
83
+ - A writes a scalar object or bit-field M, B reads the value written by
84
+ A from M, and A is sequenced before B, or
85
+ - for some evaluation X, A carries a dependency to X, and X carries a
86
+ dependency to B.
87
 
88
  [*Note 6*: “Carries a dependency to” is a subset of “is sequenced
89
  before”, and is similarly strictly intra-thread. — *end note*]
90
 
91
+ An evaluation A is *dependency-ordered before* an evaluation B if
92
 
93
+ - A performs a release operation on an atomic object M, and, in another
94
+ thread, B performs a consume operation on M and reads the value
95
+ written by A, or
96
+ - for some evaluation X, A is dependency-ordered before X and X carries
97
+ a dependency to B.
 
98
 
99
  [*Note 7*: The relation “is dependency-ordered before” is analogous to
100
  “synchronizes with”, but uses release/consume in place of
101
  release/acquire. — *end note*]
102
 
103
+ An evaluation A *inter-thread happens before* an evaluation B if
104
 
105
+ - A synchronizes with B, or
106
+ - A is dependency-ordered before B, or
107
+ - for some evaluation X
108
+ - A synchronizes with X and X is sequenced before B, or
109
+ - A is sequenced before X and X inter-thread happens before B, or
110
+ - A inter-thread happens before X and X inter-thread happens before B.
 
 
111
 
112
  [*Note 8*: The “inter-thread happens before” relation describes
113
  arbitrary concatenations of “sequenced before”, “synchronizes with” and
114
  “dependency-ordered before” relationships, with two exceptions. The
115
  first exception is that a concatenation is not permitted to end with
 
124
  of “sequenced before”. The reasons for this limitation are (1) to permit
125
  “inter-thread happens before” to be transitively closed and (2) the
126
  “happens before” relation, defined below, provides for relationships
127
  consisting entirely of “sequenced before”. — *end note*]
128
 
129
+ An evaluation A *happens before* an evaluation B (or, equivalently, B
130
+ *happens after* A) if:
131
 
132
+ - A is sequenced before B, or
133
+ - A inter-thread happens before B.
134
 
135
  The implementation shall ensure that no program execution demonstrates a
136
  cycle in the “happens before” relation.
137
 
138
  [*Note 9*: This cycle would otherwise be possible only through the use
139
  of consume operations. — *end note*]
140
 
141
+ An evaluation A *simply happens before* an evaluation B if either
142
 
143
+ - A is sequenced before B, or
144
+ - A synchronizes with B, or
145
+ - A simply happens before X and X simply happens before B.
146
 
147
  [*Note 10*: In the absence of consume operations, the happens before
148
+ and simply happens before relations are identical. *end note*]
 
149
 
150
+ An evaluation A *strongly happens before* an evaluation D if, either
 
151
 
152
+ - A is sequenced before D, or
153
+ - A synchronizes with D, and both A and D are sequentially consistent
154
+ atomic operations [[atomics.order]], or
155
+ - there are evaluations B and C such that A is sequenced before B, B
156
+ simply happens before C, and C is sequenced before D, or
157
+ - there is an evaluation B such that A strongly happens before B, and B
158
+ strongly happens before D.
159
 
160
+ [*Note 11*: Informally, if A strongly happens before B, then A appears
161
+ to be evaluated before B in all contexts. Strongly happens before
162
+ excludes consume operations. — *end note*]
163
 
164
+ A *visible side effect* A on a scalar object or bit-field M with respect
165
+ to a value computation B of M satisfies the conditions:
166
+
167
+ - A happens before B and
168
+ - there is no other side effect X to M such that A happens before X and
169
+ X happens before B.
170
+
171
+ The value of a non-atomic scalar object or bit-field M, as determined by
172
+ evaluation B, shall be the value stored by the visible side effect A.
173
+
174
+ [*Note 12*: If there is ambiguity about which side effect to a
175
  non-atomic object or bit-field is visible, then the behavior is either
176
  unspecified or undefined. — *end note*]
177
 
178
+ [*Note 13*: This states that operations on ordinary objects are not
179
  visibly reordered. This is not actually detectable without data races,
180
  but it is necessary to ensure that data races, as defined below, and
181
  with suitable restrictions on the use of atomics, correspond to data
182
  races in a simple interleaved (sequentially consistent)
183
  execution. — *end note*]
184
 
185
+ The value of an atomic object M, as determined by evaluation B, shall be
186
+ the value stored by some side effect A that modifies M, where B does not
187
+ happen before A.
188
 
189
+ [*Note 14*: The set of such side effects is also restricted by the rest
190
  of the rules described here, and in particular, by the coherence
191
  requirements below. — *end note*]
192
 
193
+ If an operation A that modifies an atomic object M happens before an
194
+ operation B that modifies M, then A shall be earlier than B in the
195
+ modification order of M.
196
 
197
+ [*Note 15*: This requirement is known as write-write
198
  coherence. — *end note*]
199
 
200
+ If a value computation A of an atomic object M happens before a value
201
+ computation B of M, and A takes its value from a side effect X on M,
202
+ then the value computed by B shall either be the value stored by X or
203
+ the value stored by a side effect Y on M, where Y follows X in the
204
+ modification order of M.
205
 
206
+ [*Note 16*: This requirement is known as read-read
207
  coherence. — *end note*]
208
 
209
+ If a value computation A of an atomic object M happens before an
210
+ operation B that modifies M, then A shall take its value from a side
211
+ effect X on M, where X precedes B in the modification order of M.
 
212
 
213
+ [*Note 17*: This requirement is known as read-write
214
  coherence. — *end note*]
215
 
216
+ If a side effect X on an atomic object M happens before a value
217
+ computation B of M, then the evaluation B shall take its value from X or
218
+ from a side effect Y that follows X in the modification order of M.
 
219
 
220
+ [*Note 18*: This requirement is known as write-read
221
  coherence. — *end note*]
222
 
223
+ [*Note 19*: The four preceding coherence requirements effectively
224
  disallow compiler reordering of atomic operations to a single object,
225
  even if both operations are relaxed loads. This effectively makes the
226
+ cache coherence guarantee provided by most hardware available to C++
227
+ atomic operations. — *end note*]
228
 
229
+ [*Note 20*: The value observed by a load of an atomic depends on the
230
  “happens before” relation, which depends on the values observed by loads
231
  of atomics. The intended reading is that there must exist an association
232
  of atomic loads with modifications they observe that, together with
233
  suitably chosen modification orders and the “happens before” relation
234
  derived as described above, satisfy the resulting constraints as imposed
 
244
  potentially concurrent conflicting actions, at least one of which is not
245
  atomic, and neither happens before the other, except for the special
246
  case for signal handlers described below. Any such data race results in
247
  undefined behavior.
248
 
249
+ [*Note 21*: It can be shown that programs that correctly use mutexes
250
+ and `memory_order::seq_cst` operations to prevent all data races and use
251
  no other synchronization operations behave as if the operations executed
252
  by their constituent threads were simply interleaved, with each value
253
  computation of an object being taken from the last side effect on that
254
  object in that interleaving. This is normally referred to as “sequential
255
  consistency”. However, this applies only to data-race-free programs, and
 
261
 
262
  Two accesses to the same object of type `volatile std::sig_atomic_t` do
263
  not result in a data race if both occur in the same thread, even if one
264
  or more occurs in a signal handler. For each signal handler invocation,
265
  evaluations performed by the thread invoking a signal handler can be
266
+ divided into two groups A and B, such that no evaluations in B happen
267
+ before evaluations in A, and the evaluations of such
268
  `volatile std::sig_atomic_t` objects take values as though all
269
+ evaluations in A happened before the execution of the signal handler and
270
+ the execution of the signal handler happened before all evaluations in
271
+ B.
272
 
273
+ [*Note 22*: Compiler transformations that introduce assignments to a
274
  potentially shared memory location that would not be modified by the
275
+ abstract machine are generally precluded by this document, since such an
276
+ assignment might overwrite another assignment by a different thread in
277
+ cases in which an abstract machine execution would not have encountered
278
+ a data race. This includes implementations of data member assignment
279
+ that overwrite adjacent members in separate memory locations. Reordering
280
+ of atomic loads in cases in which the atomics in question may alias is
281
+ also generally precluded, since this may violate the coherence
282
+ rules. — *end note*]
283
 
284
+ [*Note 23*: Transformations that introduce a speculative read of a
285
  potentially shared memory location may not preserve the semantics of the
286
+ C++ program as defined in this document, since they potentially
287
+ introduce a data race. However, they are typically valid in the context
288
+ of an optimizing compiler that targets a specific machine with
289
+ well-defined semantics for data races. They would be invalid for a
290
  hypothetical machine that is not tolerant of races or provides hardware
291
  race detection. — *end note*]
292