- tmp/tmprru19b9u/{from.md → to.md} +201 -89
tmp/tmprru19b9u/{from.md → to.md}
RENAMED
|
@@ -1,64 +1,108 @@
|
|
| 1 |
## Constant expressions <a id="expr.const">[[expr.const]]</a>
|
| 2 |
|
| 3 |
Certain contexts require expressions that satisfy additional
|
| 4 |
-
requirements as detailed in this
|
| 5 |
different semantics depending on whether or not an expression satisfies
|
| 6 |
-
these requirements. Expressions that satisfy these requirements
|
| 7 |
-
|
| 8 |
-
|
|
|
|
|
|
|
|
|
|
| 9 |
|
| 10 |
``` bnf
|
| 11 |
constant-expression:
|
| 12 |
conditional-expression
|
| 13 |
```
|
| 14 |
|
| 15 |
-
|
| 16 |
-
|
| 17 |
[[intro.execution]]), would evaluate one of the following expressions:
|
| 18 |
|
| 19 |
-
- `this` ([[expr.prim.
|
| 20 |
-
|
| 21 |
-
- an invocation of a function other than a
|
| 22 |
-
literal class, a
|
| 23 |
-
trivial destructor ([[class.dtor]]) Overload resolution (
|
| 24 |
-
[[over.match]]) is applied as usual ;
|
| 25 |
-
- an invocation of an undefined
|
| 26 |
-
|
|
|
|
|
|
|
|
|
|
| 27 |
- an expression that would exceed the implementation-defined limits (see
|
| 28 |
Annex [[implimits]]);
|
| 29 |
-
- an operation that would have undefined behavior
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
certain
|
| 33 |
-
|
|
|
|
| 34 |
- an lvalue-to-rvalue conversion ([[conv.lval]]) unless it is applied
|
| 35 |
to
|
| 36 |
- a non-volatile glvalue of integral or enumeration type that refers
|
| 37 |
-
to a non-volatile const object with a preceding
|
| 38 |
-
initialized with a constant expression
|
| 39 |
-
|
|
|
|
| 40 |
- a non-volatile glvalue that refers to a non-volatile object defined
|
| 41 |
-
with `constexpr`, or that refers to a non-mutable
|
| 42 |
an object, or
|
| 43 |
- a non-volatile glvalue of literal type that refers to a non-volatile
|
| 44 |
object whose lifetime began within the evaluation of `e`;
|
| 45 |
-
- an lvalue-to-rvalue conversion ([[conv.lval]])
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
- an *id-expression* that refers to a variable or data member of
|
| 50 |
reference type unless the reference has a preceding initialization and
|
| 51 |
either
|
| 52 |
- it is initialized with a constant expression or
|
| 53 |
-
-
|
| 54 |
-
within the evaluation of `e`;
|
| 55 |
- in a *lambda-expression*, a reference to `this` or to a variable with
|
| 56 |
automatic storage duration defined outside that *lambda-expression*,
|
| 57 |
where the reference would be an odr-use ([[basic.def.odr]],
|
| 58 |
[[expr.prim.lambda]]);
|
| 59 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
- a dynamic cast ([[expr.dynamic.cast]]);
|
| 61 |
- a `reinterpret_cast` ([[expr.reinterpret.cast]]);
|
| 62 |
- a pseudo-destructor call ([[expr.pseudo]]);
|
| 63 |
- modification of an object ([[expr.ass]], [[expr.post.incr]],
|
| 64 |
[[expr.pre.incr]]) unless it is applied to a non-volatile lvalue of
|
|
@@ -68,27 +112,33 @@ the evaluation of `e`, following the rules of the abstract machine (
|
|
| 68 |
polymorphic class type;
|
| 69 |
- a *new-expression* ([[expr.new]]);
|
| 70 |
- a *delete-expression* ([[expr.delete]]);
|
| 71 |
- a relational ([[expr.rel]]) or equality ([[expr.eq]]) operator where
|
| 72 |
the result is unspecified; or
|
| 73 |
-
- a *throw-expression* ([[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
|
| 75 |
``` cpp
|
| 76 |
int x; // not constant
|
| 77 |
struct A {
|
| 78 |
constexpr A(bool b) : m(b?42:x) { }
|
| 79 |
int m;
|
| 80 |
};
|
| 81 |
-
constexpr int v = A(true).m; // OK: constructor call initializes
|
| 82 |
-
|
| 83 |
-
constexpr int w = A(false).m; // error: initializer for m is
|
| 84 |
-
// x, which is non-constant
|
| 85 |
|
| 86 |
constexpr int f1(int k) {
|
| 87 |
-
constexpr int x = k; // error: x is not initialized by a
|
| 88 |
-
//
|
| 89 |
-
// began outside the initializer of x
|
| 90 |
return x;
|
| 91 |
}
|
| 92 |
constexpr int f2(int k) {
|
| 93 |
int x = k; // OK: not required to be a constant expression
|
| 94 |
// because x is not constexpr
|
|
@@ -97,77 +147,116 @@ constexpr int f2(int k) {
|
|
| 97 |
|
| 98 |
constexpr int incr(int &n) {
|
| 99 |
return ++n;
|
| 100 |
}
|
| 101 |
constexpr int g(int k) {
|
| 102 |
-
constexpr int x = incr(k); // error: incr(k) is not a core constant
|
| 103 |
-
//
|
| 104 |
-
// began outside the expression incr(k)
|
| 105 |
return x;
|
| 106 |
}
|
| 107 |
constexpr int h(int k) {
|
| 108 |
-
int x = incr(k); // OK: incr(k) is not required to be a core
|
| 109 |
-
// constant expression
|
| 110 |
return x;
|
| 111 |
}
|
| 112 |
constexpr int y = h(1); // OK: initializes y with the value 2
|
| 113 |
// h(1) is a core constant expression because
|
| 114 |
// the lifetime of k begins inside h(1)
|
| 115 |
```
|
| 116 |
|
|
|
|
|
|
|
| 117 |
An *integral constant expression* is an expression of integral or
|
| 118 |
unscoped enumeration type, implicitly converted to a prvalue, where the
|
| 119 |
-
converted expression is a core constant expression.
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
[[expr.new]]), as case expressions ([[stmt.switch]]), as enumerator
|
| 131 |
initializers if the underlying type is fixed ([[dcl.enum]]), as array
|
| 132 |
-
bounds ([[dcl.array]]), and as
|
| 133 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 134 |
|
| 135 |
A *constant expression* is either a glvalue core constant expression
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
|
| 140 |
-
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 146 |
|
| 147 |
Since this International Standard imposes no restrictions on the
|
| 148 |
accuracy of floating-point operations, it is unspecified whether the
|
| 149 |
evaluation of a floating-point expression during translation yields the
|
| 150 |
same result as the evaluation of the same expression (or the same
|
| 151 |
operations on the same values) during program execution.[^28]
|
| 152 |
|
|
|
|
|
|
|
| 153 |
``` cpp
|
| 154 |
bool f() {
|
| 155 |
char array[1 + int(1 + 0.2 - 0.1 - 0.1)]; // Must be evaluated during translation
|
| 156 |
int size = 1 + int(1 + 0.2 - 0.1 - 0.1); // May be evaluated at runtime
|
| 157 |
return sizeof(array) == size;
|
| 158 |
}
|
| 159 |
```
|
| 160 |
|
| 161 |
It is unspecified whether the value of `f()` will be `true` or `false`.
|
| 162 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 163 |
If an expression of literal class type is used in a context where an
|
| 164 |
integral constant expression is required, then that expression is
|
| 165 |
contextually implicitly converted (Clause [[conv]]) to an integral or
|
| 166 |
unscoped enumeration type and the selected conversion function shall be
|
| 167 |
`constexpr`.
|
| 168 |
|
|
|
|
|
|
|
| 169 |
``` cpp
|
| 170 |
struct A {
|
| 171 |
constexpr A(int i) : val(i) { }
|
| 172 |
constexpr operator int() const { return val; }
|
| 173 |
constexpr operator long() const { return 43; }
|
|
@@ -178,18 +267,21 @@ template<int> struct X { };
|
|
| 178 |
constexpr A a = 42;
|
| 179 |
X<a> x; // OK: unique conversion to int
|
| 180 |
int ary[a]; // error: ambiguous conversion
|
| 181 |
```
|
| 182 |
|
|
|
|
|
|
|
| 183 |
<!-- Link reference definitions -->
|
| 184 |
[bad.alloc]: language.md#bad.alloc
|
| 185 |
[bad.cast]: language.md#bad.cast
|
| 186 |
[bad.typeid]: language.md#bad.typeid
|
| 187 |
[basic.align]: basic.md#basic.align
|
| 188 |
[basic.compound]: basic.md#basic.compound
|
| 189 |
[basic.def.odr]: basic.md#basic.def.odr
|
| 190 |
[basic.fundamental]: basic.md#basic.fundamental
|
|
|
|
| 191 |
[basic.lookup]: basic.md#basic.lookup
|
| 192 |
[basic.lookup.argdep]: basic.md#basic.lookup.argdep
|
| 193 |
[basic.lookup.classref]: basic.md#basic.lookup.classref
|
| 194 |
[basic.lookup.unqual]: basic.md#basic.lookup.unqual
|
| 195 |
[basic.lval]: basic.md#basic.lval
|
|
@@ -215,40 +307,46 @@ int ary[a]; // error: ambiguous conversion
|
|
| 215 |
[class.copy]: special.md#class.copy
|
| 216 |
[class.ctor]: special.md#class.ctor
|
| 217 |
[class.derived]: class.md#class.derived
|
| 218 |
[class.dtor]: special.md#class.dtor
|
| 219 |
[class.free]: special.md#class.free
|
|
|
|
| 220 |
[class.init]: special.md#class.init
|
| 221 |
[class.mem]: class.md#class.mem
|
| 222 |
[class.member.lookup]: class.md#class.member.lookup
|
| 223 |
[class.mfct]: class.md#class.mfct
|
| 224 |
[class.mfct.non-static]: class.md#class.mfct.non-static
|
| 225 |
[class.name]: class.md#class.name
|
| 226 |
[class.qual]: basic.md#class.qual
|
| 227 |
[class.static]: class.md#class.static
|
| 228 |
[class.temporary]: special.md#class.temporary
|
| 229 |
[class.this]: class.md#class.this
|
|
|
|
| 230 |
[class.virtual]: class.md#class.virtual
|
| 231 |
[conv]: conv.md#conv
|
| 232 |
[conv.array]: conv.md#conv.array
|
| 233 |
[conv.bool]: conv.md#conv.bool
|
|
|
|
| 234 |
[conv.fpint]: conv.md#conv.fpint
|
| 235 |
[conv.fpprom]: conv.md#conv.fpprom
|
| 236 |
[conv.func]: conv.md#conv.func
|
| 237 |
[conv.integral]: conv.md#conv.integral
|
| 238 |
[conv.lval]: conv.md#conv.lval
|
| 239 |
[conv.mem]: conv.md#conv.mem
|
| 240 |
[conv.prom]: conv.md#conv.prom
|
| 241 |
[conv.ptr]: conv.md#conv.ptr
|
| 242 |
[conv.qual]: conv.md#conv.qual
|
|
|
|
|
|
|
|
|
|
| 243 |
[dcl.align]: dcl.md#dcl.align
|
| 244 |
[dcl.array]: dcl.md#dcl.array
|
|
|
|
| 245 |
[dcl.dcl]: dcl.md#dcl.dcl
|
| 246 |
[dcl.enum]: dcl.md#dcl.enum
|
| 247 |
[dcl.fct]: dcl.md#dcl.fct
|
| 248 |
[dcl.fct.def]: dcl.md#dcl.fct.def
|
| 249 |
-
[dcl.fct.def.delete]: dcl.md#dcl.fct.def.delete
|
| 250 |
[dcl.fct.def.general]: dcl.md#dcl.fct.def.general
|
| 251 |
[dcl.fct.default]: dcl.md#dcl.fct.default
|
| 252 |
[dcl.init]: dcl.md#dcl.init
|
| 253 |
[dcl.init.aggr]: dcl.md#dcl.init.aggr
|
| 254 |
[dcl.init.list]: dcl.md#dcl.init.list
|
|
@@ -256,17 +354,18 @@ int ary[a]; // error: ambiguous conversion
|
|
| 256 |
[dcl.link]: dcl.md#dcl.link
|
| 257 |
[dcl.name]: dcl.md#dcl.name
|
| 258 |
[dcl.ref]: dcl.md#dcl.ref
|
| 259 |
[dcl.spec.auto]: dcl.md#dcl.spec.auto
|
| 260 |
[dcl.stc]: dcl.md#dcl.stc
|
|
|
|
| 261 |
[dcl.type]: dcl.md#dcl.type
|
| 262 |
[dcl.type.cv]: dcl.md#dcl.type.cv
|
| 263 |
[dcl.type.simple]: dcl.md#dcl.type.simple
|
| 264 |
-
[depr]: future.md#depr
|
| 265 |
[except]: except.md#except
|
| 266 |
[except.handle]: except.md#except.handle
|
| 267 |
[except.spec]: except.md#except.spec
|
|
|
|
| 268 |
[except.throw]: except.md#except.throw
|
| 269 |
[expr]: #expr
|
| 270 |
[expr.add]: #expr.add
|
| 271 |
[expr.alignof]: #expr.alignof
|
| 272 |
[expr.ass]: #expr.ass
|
|
@@ -288,56 +387,76 @@ int ary[a]; // error: ambiguous conversion
|
|
| 288 |
[expr.or]: #expr.or
|
| 289 |
[expr.post]: #expr.post
|
| 290 |
[expr.post.incr]: #expr.post.incr
|
| 291 |
[expr.pre.incr]: #expr.pre.incr
|
| 292 |
[expr.prim]: #expr.prim
|
| 293 |
-
[expr.prim.
|
|
|
|
|
|
|
|
|
|
| 294 |
[expr.prim.lambda]: #expr.prim.lambda
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 295 |
[expr.pseudo]: #expr.pseudo
|
| 296 |
[expr.ref]: #expr.ref
|
| 297 |
[expr.reinterpret.cast]: #expr.reinterpret.cast
|
| 298 |
[expr.rel]: #expr.rel
|
| 299 |
[expr.shift]: #expr.shift
|
| 300 |
[expr.sizeof]: #expr.sizeof
|
| 301 |
[expr.static.cast]: #expr.static.cast
|
| 302 |
[expr.sub]: #expr.sub
|
|
|
|
| 303 |
[expr.type.conv]: #expr.type.conv
|
| 304 |
[expr.typeid]: #expr.typeid
|
| 305 |
[expr.unary]: #expr.unary
|
| 306 |
[expr.unary.noexcept]: #expr.unary.noexcept
|
| 307 |
[expr.unary.op]: #expr.unary.op
|
| 308 |
[expr.xor]: #expr.xor
|
| 309 |
[function.objects]: utilities.md#function.objects
|
| 310 |
[implimits]: limits.md#implimits
|
|
|
|
| 311 |
[intro.execution]: intro.md#intro.execution
|
| 312 |
[intro.memory]: intro.md#intro.memory
|
| 313 |
[intro.object]: intro.md#intro.object
|
| 314 |
[lex.literal]: lex.md#lex.literal
|
| 315 |
[lex.string]: lex.md#lex.string
|
|
|
|
| 316 |
[namespace.qual]: basic.md#namespace.qual
|
| 317 |
[new.badlength]: language.md#new.badlength
|
| 318 |
[new.delete.array]: language.md#new.delete.array
|
|
|
|
| 319 |
[new.delete.single]: language.md#new.delete.single
|
| 320 |
[over]: over.md#over
|
| 321 |
[over.ass]: over.md#over.ass
|
|
|
|
| 322 |
[over.built]: over.md#over.built
|
| 323 |
[over.call]: over.md#over.call
|
| 324 |
[over.ics.user]: over.md#over.ics.user
|
| 325 |
[over.literal]: over.md#over.literal
|
| 326 |
[over.match]: over.md#over.match
|
|
|
|
| 327 |
[over.match.oper]: over.md#over.match.oper
|
|
|
|
| 328 |
[over.oper]: over.md#over.oper
|
| 329 |
[over.over]: over.md#over.over
|
| 330 |
[replacement.functions]: library.md#replacement.functions
|
|
|
|
| 331 |
[stmt.switch]: stmt.md#stmt.switch
|
| 332 |
[support.runtime]: language.md#support.runtime
|
| 333 |
[support.types]: language.md#support.types
|
|
|
|
| 334 |
[temp.arg]: temp.md#temp.arg
|
|
|
|
|
|
|
| 335 |
[temp.mem]: temp.md#temp.mem
|
| 336 |
[temp.names]: temp.md#temp.names
|
| 337 |
[temp.res]: temp.md#temp.res
|
| 338 |
[temp.variadic]: temp.md#temp.variadic
|
|
|
|
| 339 |
[type.info]: language.md#type.info
|
| 340 |
|
| 341 |
[^1]: The precedence of operators is not directly specified, but it can
|
| 342 |
be derived from the syntax.
|
| 343 |
|
|
@@ -408,41 +527,34 @@ int ary[a]; // error: ambiguous conversion
|
|
| 408 |
expression is enclosed in parentheses.
|
| 409 |
|
| 410 |
[^21]: This implies that an object cannot be deleted using a pointer of
|
| 411 |
type `void*` because `void` is not an object type.
|
| 412 |
|
| 413 |
-
[^22]: For
|
| 414 |
first element of the array created by that *new-expression*.
|
| 415 |
Zero-length arrays do not have a first element.
|
| 416 |
|
| 417 |
[^23]: If the static type of the object to be deleted is complete and is
|
| 418 |
different from the dynamic type, and the destructor is not virtual,
|
| 419 |
the size might be incorrect, but that case is already undefined, as
|
| 420 |
stated above.
|
| 421 |
|
| 422 |
-
[^24]: This
|
| 423 |
-
function in a *new-expression*.
|
| 424 |
|
| 425 |
-
[^25]:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 426 |
|
| 427 |
-
[^26]:
|
| 428 |
-
|
| 429 |
-
|
| 430 |
-
|
| 431 |
-
|
| 432 |
-
original type. For pointer subtraction, the result of the difference
|
| 433 |
-
between the character pointers is similarly divided by the size of
|
| 434 |
-
the object originally pointed to.
|
| 435 |
|
| 436 |
-
|
| 437 |
-
|
| 438 |
-
after the end of the object in order to satisfy the “one past the
|
| 439 |
-
last element” requirements.
|
| 440 |
-
|
| 441 |
-
[^27]: However, an invocation of an overloaded comma operator is an
|
| 442 |
-
ordinary function call; hence, the evaluations of its argument
|
| 443 |
-
expressions are unsequenced relative to one another (see
|
| 444 |
-
[[intro.execution]]).
|
| 445 |
|
| 446 |
[^28]: Nonetheless, implementations are encouraged to provide consistent
|
| 447 |
results, irrespective of whether the evaluation was performed during
|
| 448 |
translation and/or during program execution.
|
|
|
|
| 1 |
## Constant expressions <a id="expr.const">[[expr.const]]</a>
|
| 2 |
|
| 3 |
Certain contexts require expressions that satisfy additional
|
| 4 |
+
requirements as detailed in this subclause; other contexts have
|
| 5 |
different semantics depending on whether or not an expression satisfies
|
| 6 |
+
these requirements. Expressions that satisfy these requirements,
|
| 7 |
+
assuming that copy elision is performed, are called *constant
|
| 8 |
+
expressions*.
|
| 9 |
+
|
| 10 |
+
[*Note 1*: Constant expressions can be evaluated during
|
| 11 |
+
translation. — *end note*]
|
| 12 |
|
| 13 |
``` bnf
|
| 14 |
constant-expression:
|
| 15 |
conditional-expression
|
| 16 |
```
|
| 17 |
|
| 18 |
+
An expression `e` is a *core constant expression* unless the evaluation
|
| 19 |
+
of `e`, following the rules of the abstract machine (
|
| 20 |
[[intro.execution]]), would evaluate one of the following expressions:
|
| 21 |
|
| 22 |
+
- `this` ([[expr.prim.this]]), except in a constexpr function or a
|
| 23 |
+
constexpr constructor that is being evaluated as part of `e`;
|
| 24 |
+
- an invocation of a function other than a constexpr constructor for a
|
| 25 |
+
literal class, a constexpr function, or an implicit invocation of a
|
| 26 |
+
trivial destructor ([[class.dtor]]) \[*Note 2*: Overload resolution (
|
| 27 |
+
[[over.match]]) is applied as usual — *end note*] ;
|
| 28 |
+
- an invocation of an undefined constexpr function or an undefined
|
| 29 |
+
constexpr constructor;
|
| 30 |
+
- an invocation of an instantiated constexpr function or constexpr
|
| 31 |
+
constructor that fails to satisfy the requirements for a constexpr
|
| 32 |
+
function or constexpr constructor ([[dcl.constexpr]]);
|
| 33 |
- an expression that would exceed the implementation-defined limits (see
|
| 34 |
Annex [[implimits]]);
|
| 35 |
+
- an operation that would have undefined behavior as specified in
|
| 36 |
+
Clauses [[intro]] through [[cpp]] of this International Standard
|
| 37 |
+
\[*Note 3*: including, for example, signed integer overflow (Clause
|
| 38 |
+
[[expr]]), certain pointer arithmetic ([[expr.add]]), division by
|
| 39 |
+
zero ([[expr.mul]]), or certain shift operations (
|
| 40 |
+
[[expr.shift]]) — *end note*] ;
|
| 41 |
- an lvalue-to-rvalue conversion ([[conv.lval]]) unless it is applied
|
| 42 |
to
|
| 43 |
- a non-volatile glvalue of integral or enumeration type that refers
|
| 44 |
+
to a complete non-volatile const object with a preceding
|
| 45 |
+
initialization, initialized with a constant expression, or
|
| 46 |
+
- a non-volatile glvalue that refers to a subobject of a string
|
| 47 |
+
literal ([[lex.string]]), or
|
| 48 |
- a non-volatile glvalue that refers to a non-volatile object defined
|
| 49 |
+
with `constexpr`, or that refers to a non-mutable subobject of such
|
| 50 |
an object, or
|
| 51 |
- a non-volatile glvalue of literal type that refers to a non-volatile
|
| 52 |
object whose lifetime began within the evaluation of `e`;
|
| 53 |
+
- an lvalue-to-rvalue conversion ([[conv.lval]]) that is applied to a
|
| 54 |
+
glvalue that refers to a non-active member of a union or a subobject
|
| 55 |
+
thereof;
|
| 56 |
+
- an invocation of an implicitly-defined copy/move constructor or
|
| 57 |
+
copy/move assignment operator for a union whose active member (if any)
|
| 58 |
+
is mutable, unless the lifetime of the union object began within the
|
| 59 |
+
evaluation of `e`;
|
| 60 |
+
- an assignment expression ([[expr.ass]]) or invocation of an
|
| 61 |
+
assignment operator ([[class.copy]]) that would change the active
|
| 62 |
+
member of a union;
|
| 63 |
- an *id-expression* that refers to a variable or data member of
|
| 64 |
reference type unless the reference has a preceding initialization and
|
| 65 |
either
|
| 66 |
- it is initialized with a constant expression or
|
| 67 |
+
- its lifetime began within the evaluation of `e`;
|
|
|
|
| 68 |
- in a *lambda-expression*, a reference to `this` or to a variable with
|
| 69 |
automatic storage duration defined outside that *lambda-expression*,
|
| 70 |
where the reference would be an odr-use ([[basic.def.odr]],
|
| 71 |
[[expr.prim.lambda]]);
|
| 72 |
+
\[*Example 1*:
|
| 73 |
+
``` cpp
|
| 74 |
+
void g() {
|
| 75 |
+
const int n = 0;
|
| 76 |
+
[=] {
|
| 77 |
+
constexpr int i = n; // OK, n is not odr-used and not captured here
|
| 78 |
+
constexpr int j = *&n; // ill-formed, &n would be an odr-use of n
|
| 79 |
+
};
|
| 80 |
+
}
|
| 81 |
+
```
|
| 82 |
+
|
| 83 |
+
— *end example*]
|
| 84 |
+
\[*Note 4*:
|
| 85 |
+
If the odr-use occurs in an invocation of a function call operator of
|
| 86 |
+
a closure type, it no longer refers to `this` or to an enclosing
|
| 87 |
+
automatic variable due to the transformation (
|
| 88 |
+
[[expr.prim.lambda.capture]]) of the *id-expression* into an access of
|
| 89 |
+
the corresponding data member.
|
| 90 |
+
\[*Example 2*:
|
| 91 |
+
``` cpp
|
| 92 |
+
auto monad = [](auto v) { return [=] { return v; }; };
|
| 93 |
+
auto bind = [](auto m) {
|
| 94 |
+
return [=](auto fvm) { return fvm(m()); };
|
| 95 |
+
};
|
| 96 |
+
|
| 97 |
+
// OK to have captures to automatic objects created during constant expression evaluation.
|
| 98 |
+
static_assert(bind(monad(2))(monad)() == monad(2)());
|
| 99 |
+
```
|
| 100 |
+
|
| 101 |
+
— *end example*]
|
| 102 |
+
— *end note*]
|
| 103 |
+
- a conversion from type cv `void*` to a pointer-to-object type;
|
| 104 |
- a dynamic cast ([[expr.dynamic.cast]]);
|
| 105 |
- a `reinterpret_cast` ([[expr.reinterpret.cast]]);
|
| 106 |
- a pseudo-destructor call ([[expr.pseudo]]);
|
| 107 |
- modification of an object ([[expr.ass]], [[expr.post.incr]],
|
| 108 |
[[expr.pre.incr]]) unless it is applied to a non-volatile lvalue of
|
|
|
|
| 112 |
polymorphic class type;
|
| 113 |
- a *new-expression* ([[expr.new]]);
|
| 114 |
- a *delete-expression* ([[expr.delete]]);
|
| 115 |
- a relational ([[expr.rel]]) or equality ([[expr.eq]]) operator where
|
| 116 |
the result is unspecified; or
|
| 117 |
+
- a *throw-expression* ([[expr.throw]]).
|
| 118 |
+
|
| 119 |
+
If `e` satisfies the constraints of a core constant expression, but
|
| 120 |
+
evaluation of `e` would evaluate an operation that has undefined
|
| 121 |
+
behavior as specified in Clauses [[library]] through [[thread]] of
|
| 122 |
+
this International Standard, it is unspecified whether `e` is a core
|
| 123 |
+
constant expression.
|
| 124 |
+
|
| 125 |
+
[*Example 3*:
|
| 126 |
|
| 127 |
``` cpp
|
| 128 |
int x; // not constant
|
| 129 |
struct A {
|
| 130 |
constexpr A(bool b) : m(b?42:x) { }
|
| 131 |
int m;
|
| 132 |
};
|
| 133 |
+
constexpr int v = A(true).m; // OK: constructor call initializes m with the value 42
|
| 134 |
+
|
| 135 |
+
constexpr int w = A(false).m; // error: initializer for m is x, which is non-constant
|
|
|
|
| 136 |
|
| 137 |
constexpr int f1(int k) {
|
| 138 |
+
constexpr int x = k; // error: x is not initialized by a constant expression
|
| 139 |
+
// because lifetime of k began outside the initializer of x
|
|
|
|
| 140 |
return x;
|
| 141 |
}
|
| 142 |
constexpr int f2(int k) {
|
| 143 |
int x = k; // OK: not required to be a constant expression
|
| 144 |
// because x is not constexpr
|
|
|
|
| 147 |
|
| 148 |
constexpr int incr(int &n) {
|
| 149 |
return ++n;
|
| 150 |
}
|
| 151 |
constexpr int g(int k) {
|
| 152 |
+
constexpr int x = incr(k); // error: incr(k) is not a core constant expression
|
| 153 |
+
// because lifetime of k began outside the expression incr(k)
|
|
|
|
| 154 |
return x;
|
| 155 |
}
|
| 156 |
constexpr int h(int k) {
|
| 157 |
+
int x = incr(k); // OK: incr(k) is not required to be a core constant expression
|
|
|
|
| 158 |
return x;
|
| 159 |
}
|
| 160 |
constexpr int y = h(1); // OK: initializes y with the value 2
|
| 161 |
// h(1) is a core constant expression because
|
| 162 |
// the lifetime of k begins inside h(1)
|
| 163 |
```
|
| 164 |
|
| 165 |
+
— *end example*]
|
| 166 |
+
|
| 167 |
An *integral constant expression* is an expression of integral or
|
| 168 |
unscoped enumeration type, implicitly converted to a prvalue, where the
|
| 169 |
+
converted expression is a core constant expression.
|
| 170 |
+
|
| 171 |
+
[*Note 5*: Such expressions may be used as bit-field lengths (
|
| 172 |
+
[[class.bit]]), as enumerator initializers if the underlying type is not
|
| 173 |
+
fixed ([[dcl.enum]]), and as alignments (
|
| 174 |
+
[[dcl.align]]). — *end note*]
|
| 175 |
+
|
| 176 |
+
A *converted constant expression* of type `T` is an expression,
|
| 177 |
+
implicitly converted to type `T`, where the converted expression is a
|
| 178 |
+
constant expression and the implicit conversion sequence contains only
|
| 179 |
+
|
| 180 |
+
- user-defined conversions,
|
| 181 |
+
- lvalue-to-rvalue conversions ([[conv.lval]]),
|
| 182 |
+
- array-to-pointer conversions ([[conv.array]]),
|
| 183 |
+
- function-to-pointer conversions ([[conv.func]]),
|
| 184 |
+
- qualification conversions ([[conv.qual]]),
|
| 185 |
+
- integral promotions ([[conv.prom]]),
|
| 186 |
+
- integral conversions ([[conv.integral]]) other than narrowing
|
| 187 |
+
conversions ([[dcl.init.list]]),
|
| 188 |
+
- null pointer conversions ([[conv.ptr]]) from `std::nullptr_t`,
|
| 189 |
+
- null member pointer conversions ([[conv.mem]]) from `std::nullptr_t`,
|
| 190 |
+
and
|
| 191 |
+
- function pointer conversions ([[conv.fctptr]]),
|
| 192 |
+
|
| 193 |
+
and where the reference binding (if any) binds directly.
|
| 194 |
+
|
| 195 |
+
[*Note 6*: Such expressions may be used in `new` expressions (
|
| 196 |
[[expr.new]]), as case expressions ([[stmt.switch]]), as enumerator
|
| 197 |
initializers if the underlying type is fixed ([[dcl.enum]]), as array
|
| 198 |
+
bounds ([[dcl.array]]), and as non-type template arguments (
|
| 199 |
+
[[temp.arg]]). — *end note*]
|
| 200 |
+
|
| 201 |
+
A *contextually converted constant expression of type `bool`* is an
|
| 202 |
+
expression, contextually converted to `bool` (Clause [[conv]]), where
|
| 203 |
+
the converted expression is a constant expression and the conversion
|
| 204 |
+
sequence contains only the conversions above.
|
| 205 |
|
| 206 |
A *constant expression* is either a glvalue core constant expression
|
| 207 |
+
that refers to an entity that is a permitted result of a constant
|
| 208 |
+
expression (as defined below), or a prvalue core constant expression
|
| 209 |
+
whose value satisfies the following constraints:
|
| 210 |
|
| 211 |
+
- if the value is an object of class type, each non-static data member
|
| 212 |
+
of reference type refers to an entity that is a permitted result of a
|
| 213 |
+
constant expression,
|
| 214 |
+
- if the value is of pointer type, it contains the address of an object
|
| 215 |
+
with static storage duration, the address past the end of such an
|
| 216 |
+
object ([[expr.add]]), the address of a function, or a null pointer
|
| 217 |
+
value, and
|
| 218 |
+
- if the value is an object of class or array type, each subobject
|
| 219 |
+
satisfies these constraints for the value.
|
| 220 |
+
|
| 221 |
+
An entity is a *permitted result of a constant expression* if it is an
|
| 222 |
+
object with static storage duration that is either not a temporary
|
| 223 |
+
object or is a temporary object whose value satisfies the above
|
| 224 |
+
constraints, or it is a function.
|
| 225 |
+
|
| 226 |
+
[*Note 7*:
|
| 227 |
|
| 228 |
Since this International Standard imposes no restrictions on the
|
| 229 |
accuracy of floating-point operations, it is unspecified whether the
|
| 230 |
evaluation of a floating-point expression during translation yields the
|
| 231 |
same result as the evaluation of the same expression (or the same
|
| 232 |
operations on the same values) during program execution.[^28]
|
| 233 |
|
| 234 |
+
[*Example 4*:
|
| 235 |
+
|
| 236 |
``` cpp
|
| 237 |
bool f() {
|
| 238 |
char array[1 + int(1 + 0.2 - 0.1 - 0.1)]; // Must be evaluated during translation
|
| 239 |
int size = 1 + int(1 + 0.2 - 0.1 - 0.1); // May be evaluated at runtime
|
| 240 |
return sizeof(array) == size;
|
| 241 |
}
|
| 242 |
```
|
| 243 |
|
| 244 |
It is unspecified whether the value of `f()` will be `true` or `false`.
|
| 245 |
|
| 246 |
+
— *end example*]
|
| 247 |
+
|
| 248 |
+
— *end note*]
|
| 249 |
+
|
| 250 |
If an expression of literal class type is used in a context where an
|
| 251 |
integral constant expression is required, then that expression is
|
| 252 |
contextually implicitly converted (Clause [[conv]]) to an integral or
|
| 253 |
unscoped enumeration type and the selected conversion function shall be
|
| 254 |
`constexpr`.
|
| 255 |
|
| 256 |
+
[*Example 5*:
|
| 257 |
+
|
| 258 |
``` cpp
|
| 259 |
struct A {
|
| 260 |
constexpr A(int i) : val(i) { }
|
| 261 |
constexpr operator int() const { return val; }
|
| 262 |
constexpr operator long() const { return 43; }
|
|
|
|
| 267 |
constexpr A a = 42;
|
| 268 |
X<a> x; // OK: unique conversion to int
|
| 269 |
int ary[a]; // error: ambiguous conversion
|
| 270 |
```
|
| 271 |
|
| 272 |
+
— *end example*]
|
| 273 |
+
|
| 274 |
<!-- Link reference definitions -->
|
| 275 |
[bad.alloc]: language.md#bad.alloc
|
| 276 |
[bad.cast]: language.md#bad.cast
|
| 277 |
[bad.typeid]: language.md#bad.typeid
|
| 278 |
[basic.align]: basic.md#basic.align
|
| 279 |
[basic.compound]: basic.md#basic.compound
|
| 280 |
[basic.def.odr]: basic.md#basic.def.odr
|
| 281 |
[basic.fundamental]: basic.md#basic.fundamental
|
| 282 |
+
[basic.life]: basic.md#basic.life
|
| 283 |
[basic.lookup]: basic.md#basic.lookup
|
| 284 |
[basic.lookup.argdep]: basic.md#basic.lookup.argdep
|
| 285 |
[basic.lookup.classref]: basic.md#basic.lookup.classref
|
| 286 |
[basic.lookup.unqual]: basic.md#basic.lookup.unqual
|
| 287 |
[basic.lval]: basic.md#basic.lval
|
|
|
|
| 307 |
[class.copy]: special.md#class.copy
|
| 308 |
[class.ctor]: special.md#class.ctor
|
| 309 |
[class.derived]: class.md#class.derived
|
| 310 |
[class.dtor]: special.md#class.dtor
|
| 311 |
[class.free]: special.md#class.free
|
| 312 |
+
[class.friend]: class.md#class.friend
|
| 313 |
[class.init]: special.md#class.init
|
| 314 |
[class.mem]: class.md#class.mem
|
| 315 |
[class.member.lookup]: class.md#class.member.lookup
|
| 316 |
[class.mfct]: class.md#class.mfct
|
| 317 |
[class.mfct.non-static]: class.md#class.mfct.non-static
|
| 318 |
[class.name]: class.md#class.name
|
| 319 |
[class.qual]: basic.md#class.qual
|
| 320 |
[class.static]: class.md#class.static
|
| 321 |
[class.temporary]: special.md#class.temporary
|
| 322 |
[class.this]: class.md#class.this
|
| 323 |
+
[class.union]: class.md#class.union
|
| 324 |
[class.virtual]: class.md#class.virtual
|
| 325 |
[conv]: conv.md#conv
|
| 326 |
[conv.array]: conv.md#conv.array
|
| 327 |
[conv.bool]: conv.md#conv.bool
|
| 328 |
+
[conv.fctptr]: conv.md#conv.fctptr
|
| 329 |
[conv.fpint]: conv.md#conv.fpint
|
| 330 |
[conv.fpprom]: conv.md#conv.fpprom
|
| 331 |
[conv.func]: conv.md#conv.func
|
| 332 |
[conv.integral]: conv.md#conv.integral
|
| 333 |
[conv.lval]: conv.md#conv.lval
|
| 334 |
[conv.mem]: conv.md#conv.mem
|
| 335 |
[conv.prom]: conv.md#conv.prom
|
| 336 |
[conv.ptr]: conv.md#conv.ptr
|
| 337 |
[conv.qual]: conv.md#conv.qual
|
| 338 |
+
[conv.rval]: conv.md#conv.rval
|
| 339 |
+
[cpp]: cpp.md#cpp
|
| 340 |
+
[cstddef.syn]: language.md#cstddef.syn
|
| 341 |
[dcl.align]: dcl.md#dcl.align
|
| 342 |
[dcl.array]: dcl.md#dcl.array
|
| 343 |
+
[dcl.constexpr]: dcl.md#dcl.constexpr
|
| 344 |
[dcl.dcl]: dcl.md#dcl.dcl
|
| 345 |
[dcl.enum]: dcl.md#dcl.enum
|
| 346 |
[dcl.fct]: dcl.md#dcl.fct
|
| 347 |
[dcl.fct.def]: dcl.md#dcl.fct.def
|
|
|
|
| 348 |
[dcl.fct.def.general]: dcl.md#dcl.fct.def.general
|
| 349 |
[dcl.fct.default]: dcl.md#dcl.fct.default
|
| 350 |
[dcl.init]: dcl.md#dcl.init
|
| 351 |
[dcl.init.aggr]: dcl.md#dcl.init.aggr
|
| 352 |
[dcl.init.list]: dcl.md#dcl.init.list
|
|
|
|
| 354 |
[dcl.link]: dcl.md#dcl.link
|
| 355 |
[dcl.name]: dcl.md#dcl.name
|
| 356 |
[dcl.ref]: dcl.md#dcl.ref
|
| 357 |
[dcl.spec.auto]: dcl.md#dcl.spec.auto
|
| 358 |
[dcl.stc]: dcl.md#dcl.stc
|
| 359 |
+
[dcl.struct.bind]: dcl.md#dcl.struct.bind
|
| 360 |
[dcl.type]: dcl.md#dcl.type
|
| 361 |
[dcl.type.cv]: dcl.md#dcl.type.cv
|
| 362 |
[dcl.type.simple]: dcl.md#dcl.type.simple
|
|
|
|
| 363 |
[except]: except.md#except
|
| 364 |
[except.handle]: except.md#except.handle
|
| 365 |
[except.spec]: except.md#except.spec
|
| 366 |
+
[except.terminate]: except.md#except.terminate
|
| 367 |
[except.throw]: except.md#except.throw
|
| 368 |
[expr]: #expr
|
| 369 |
[expr.add]: #expr.add
|
| 370 |
[expr.alignof]: #expr.alignof
|
| 371 |
[expr.ass]: #expr.ass
|
|
|
|
| 387 |
[expr.or]: #expr.or
|
| 388 |
[expr.post]: #expr.post
|
| 389 |
[expr.post.incr]: #expr.post.incr
|
| 390 |
[expr.pre.incr]: #expr.pre.incr
|
| 391 |
[expr.prim]: #expr.prim
|
| 392 |
+
[expr.prim.fold]: #expr.prim.fold
|
| 393 |
+
[expr.prim.id]: #expr.prim.id
|
| 394 |
+
[expr.prim.id.qual]: #expr.prim.id.qual
|
| 395 |
+
[expr.prim.id.unqual]: #expr.prim.id.unqual
|
| 396 |
[expr.prim.lambda]: #expr.prim.lambda
|
| 397 |
+
[expr.prim.lambda.capture]: #expr.prim.lambda.capture
|
| 398 |
+
[expr.prim.lambda.closure]: #expr.prim.lambda.closure
|
| 399 |
+
[expr.prim.literal]: #expr.prim.literal
|
| 400 |
+
[expr.prim.paren]: #expr.prim.paren
|
| 401 |
+
[expr.prim.this]: #expr.prim.this
|
| 402 |
[expr.pseudo]: #expr.pseudo
|
| 403 |
[expr.ref]: #expr.ref
|
| 404 |
[expr.reinterpret.cast]: #expr.reinterpret.cast
|
| 405 |
[expr.rel]: #expr.rel
|
| 406 |
[expr.shift]: #expr.shift
|
| 407 |
[expr.sizeof]: #expr.sizeof
|
| 408 |
[expr.static.cast]: #expr.static.cast
|
| 409 |
[expr.sub]: #expr.sub
|
| 410 |
+
[expr.throw]: #expr.throw
|
| 411 |
[expr.type.conv]: #expr.type.conv
|
| 412 |
[expr.typeid]: #expr.typeid
|
| 413 |
[expr.unary]: #expr.unary
|
| 414 |
[expr.unary.noexcept]: #expr.unary.noexcept
|
| 415 |
[expr.unary.op]: #expr.unary.op
|
| 416 |
[expr.xor]: #expr.xor
|
| 417 |
[function.objects]: utilities.md#function.objects
|
| 418 |
[implimits]: limits.md#implimits
|
| 419 |
+
[intro]: intro.md#intro
|
| 420 |
[intro.execution]: intro.md#intro.execution
|
| 421 |
[intro.memory]: intro.md#intro.memory
|
| 422 |
[intro.object]: intro.md#intro.object
|
| 423 |
[lex.literal]: lex.md#lex.literal
|
| 424 |
[lex.string]: lex.md#lex.string
|
| 425 |
+
[library]: library.md#library
|
| 426 |
[namespace.qual]: basic.md#namespace.qual
|
| 427 |
[new.badlength]: language.md#new.badlength
|
| 428 |
[new.delete.array]: language.md#new.delete.array
|
| 429 |
+
[new.delete.placement]: language.md#new.delete.placement
|
| 430 |
[new.delete.single]: language.md#new.delete.single
|
| 431 |
[over]: over.md#over
|
| 432 |
[over.ass]: over.md#over.ass
|
| 433 |
+
[over.best.ics]: over.md#over.best.ics
|
| 434 |
[over.built]: over.md#over.built
|
| 435 |
[over.call]: over.md#over.call
|
| 436 |
[over.ics.user]: over.md#over.ics.user
|
| 437 |
[over.literal]: over.md#over.literal
|
| 438 |
[over.match]: over.md#over.match
|
| 439 |
+
[over.match.class.deduct]: over.md#over.match.class.deduct
|
| 440 |
[over.match.oper]: over.md#over.match.oper
|
| 441 |
+
[over.match.viable]: over.md#over.match.viable
|
| 442 |
[over.oper]: over.md#over.oper
|
| 443 |
[over.over]: over.md#over.over
|
| 444 |
[replacement.functions]: library.md#replacement.functions
|
| 445 |
+
[stmt.return]: stmt.md#stmt.return
|
| 446 |
[stmt.switch]: stmt.md#stmt.switch
|
| 447 |
[support.runtime]: language.md#support.runtime
|
| 448 |
[support.types]: language.md#support.types
|
| 449 |
+
[support.types.layout]: language.md#support.types.layout
|
| 450 |
[temp.arg]: temp.md#temp.arg
|
| 451 |
+
[temp.expl.spec]: temp.md#temp.expl.spec
|
| 452 |
+
[temp.explicit]: temp.md#temp.explicit
|
| 453 |
[temp.mem]: temp.md#temp.mem
|
| 454 |
[temp.names]: temp.md#temp.names
|
| 455 |
[temp.res]: temp.md#temp.res
|
| 456 |
[temp.variadic]: temp.md#temp.variadic
|
| 457 |
+
[thread]: thread.md#thread
|
| 458 |
[type.info]: language.md#type.info
|
| 459 |
|
| 460 |
[^1]: The precedence of operators is not directly specified, but it can
|
| 461 |
be derived from the syntax.
|
| 462 |
|
|
|
|
| 527 |
expression is enclosed in parentheses.
|
| 528 |
|
| 529 |
[^21]: This implies that an object cannot be deleted using a pointer of
|
| 530 |
type `void*` because `void` is not an object type.
|
| 531 |
|
| 532 |
+
[^22]: For nonzero-length arrays, this is the same as a pointer to the
|
| 533 |
first element of the array created by that *new-expression*.
|
| 534 |
Zero-length arrays do not have a first element.
|
| 535 |
|
| 536 |
[^23]: If the static type of the object to be deleted is complete and is
|
| 537 |
different from the dynamic type, and the destructor is not virtual,
|
| 538 |
the size might be incorrect, but that case is already undefined, as
|
| 539 |
stated above.
|
| 540 |
|
| 541 |
+
[^24]: This is often called truncation towards zero.
|
|
|
|
| 542 |
|
| 543 |
+
[^25]: An object that is not an array element is considered to belong to
|
| 544 |
+
a single-element array for this purpose; see [[expr.unary.op]]. A
|
| 545 |
+
pointer past the last element of an array `x` of n elements is
|
| 546 |
+
considered to be equivalent to a pointer to a hypothetical element
|
| 547 |
+
x[n] for this purpose; see [[basic.compound]].
|
| 548 |
|
| 549 |
+
[^26]: An object that is not an array element is considered to belong to
|
| 550 |
+
a single-element array for this purpose; see [[expr.unary.op]]. A
|
| 551 |
+
pointer past the last element of an array `x` of n elements is
|
| 552 |
+
considered to be equivalent to a pointer to a hypothetical element
|
| 553 |
+
x[n] for this purpose; see [[basic.compound]].
|
|
|
|
|
|
|
|
|
|
| 554 |
|
| 555 |
+
[^27]: An object that is not an array element is considered to belong to
|
| 556 |
+
a single-element array for this purpose; see [[expr.unary.op]].
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 557 |
|
| 558 |
[^28]: Nonetheless, implementations are encouraged to provide consistent
|
| 559 |
results, irrespective of whether the evaluation was performed during
|
| 560 |
translation and/or during program execution.
|