From Jason Turner

[dcl.constexpr]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp3bnzi___/{from.md → to.md} +70 -114
tmp/tmp3bnzi___/{from.md → to.md} RENAMED
@@ -1,32 +1,33 @@
1
  ### The `constexpr` specifier <a id="dcl.constexpr">[[dcl.constexpr]]</a>
2
 
3
  The `constexpr` specifier shall be applied only to the definition of a
4
- variable, the declaration of a function or function template, or the
5
- declaration of a static data member of a literal type (
6
- [[basic.types]]). If any declaration of a function or function template
7
- has `constexpr` specifier, then all its declarations shall contain the
8
- `constexpr` specifier. An explicit specialization can differ from the
9
- template declaration with respect to the `constexpr` specifier. Function
10
- parameters cannot be declared `constexpr`.
 
11
 
12
  ``` cpp
13
- constexpr int square(int x); // OK: declaration
14
  constexpr int bufsz = 1024; // OK: definition
15
  constexpr struct pixel { // error: pixel is a type
16
  int x;
17
  int y;
18
  constexpr pixel(int); // OK: declaration
19
  };
20
  constexpr pixel::pixel(int a)
21
- : x(square(a)), y(square(a)) // OK: definition
22
- { }
23
  constexpr pixel small(2); // error: square not defined, so small(2)
24
  // not constant~([expr.const]) so constexpr not satisfied
25
 
26
- constexpr int square(int x) { // OK: definition
27
- return x * x;
28
  }
29
  constexpr pixel large(4); // OK: square defined
30
  int next(constexpr int x) { // error: not for parameters
31
  return x + 1;
32
  }
@@ -45,122 +46,89 @@ constraints:
45
 
46
  - it shall not be virtual ([[class.virtual]]);
47
  - its return type shall be a literal type;
48
  - each of its parameter types shall be a literal type;
49
  - its *function-body* shall be `= delete`, `= default`, or a
50
- *compound-statement* that contains only
51
- - null statements,
52
-
53
- -
54
-
55
- - `typedef` declarations and *alias-declaration*s that do not define
56
- classes or enumerations,
57
-
58
- - *using-declaration*s,
59
-
60
- - *using-directive*s,
61
-
62
- - and exactly one return statement;
63
- - every constructor call and implicit conversion used in initializing
64
- the return value ([[stmt.return]],  [[dcl.init]]) shall be one of
65
- those allowed in a constant expression ([[expr.const]]).
66
 
67
  ``` cpp
68
  constexpr int square(int x)
69
  { return x * x; } // OK
70
  constexpr long long_max()
71
  { return 2147483647; } // OK
72
- constexpr int abs(int x)
73
- { return x < 0 ? -x : x; } // OK
74
- constexpr void f(int x) // error: return type is void
75
- { /* ... */ }
 
 
 
 
 
 
 
 
 
76
  constexpr int prev(int x)
77
- { return --x; } // error: use of decrement
78
- constexpr int g(int x, int n) { // error: body not just ``return expr''
79
  int r = 1;
80
  while (--n > 0) r *= x;
81
  return r;
82
  }
83
  ```
84
 
85
- In a definition of a `constexpr` constructor, each of the parameter
86
- types shall be a literal type. In addition, either its *function-body*
87
- shall be `= delete` or `= default` or it shall satisfy the following
88
  constraints:
89
 
90
  - the class shall not have any virtual base classes;
 
91
  - its *function-body* shall not be a *function-try-block*;
92
- - the *compound-statement* of its *function-body* shall contain only
93
- - null statements,
94
 
95
- -
 
96
 
97
- - `typedef` declarations and *alias-declaration*s that do not define
98
- classes or enumerations,
99
-
100
- - *using-declaration*s,
101
-
102
- - and *using-directive*s;
103
- - every non-static data member and base class sub-object shall be
104
- initialized ([[class.base.init]]);
105
- - every constructor involved in initializing non-static data members and
106
- base class sub-objects shall be a `constexpr` constructor;
107
- - every *assignment-expression* that is an *initializer-clause*
108
- appearing directly or indirectly within a *brace-or-equal-initializer*
109
- for a non-static data member that is not named by a
110
- *mem-initializer-id* shall be a constant expression; and
111
- - every implicit conversion used in converting a constructor argument to
112
- the corresponding parameter type and converting a full-expression to
113
- the corresponding member type shall be one of those allowed in a
114
- constant expression.
115
 
116
  ``` cpp
117
  struct Length {
118
- explicit constexpr Length(int i = 0) : val(i) { }
119
  private:
120
  int val;
121
  };
122
  ```
123
 
124
- *Function invocation substitution* for a call of a `constexpr` function
125
- or of a `constexpr` constructor means implicitly converting each
126
- argument to the corresponding parameter type as if by
127
- copy-initialization,[^3] substituting that converted expression for each
128
- use of the corresponding parameter in the *function-body*, and, for
129
- `constexpr` functions, implicitly converting the resulting returned
130
- expression or *braced-init-list* to the return type of the function as
131
- if by copy-initialization. Such substitution does not change the
132
- meaning.
133
-
134
- ``` cpp
135
- constexpr int f(void *) { return 0; }
136
- constexpr int f(...) { return 1; }
137
- constexpr int g1() { return f(0); } // calls f(void *)
138
- constexpr int g2(int n) { return f(n); } // calls f(...) even for n == 0
139
- constexpr int g3(int n) { return f(n*0); } // calls f(...)
140
-
141
- namespace N {
142
- constexpr int c = 5;
143
- constexpr int h() { return c; }
144
- }
145
- constexpr int c = 0;
146
- constexpr int g4() { return N::h(); } // value is 5, c is not looked up again after the substitution
147
- ```
148
-
149
- For a `constexpr` function, if no function argument values exist such
150
- that the function invocation substitution would produce a constant
151
  expression ([[expr.const]]), the program is ill-formed; no diagnostic
152
- required. For a `constexpr` constructor, if no argument values exist
153
- such that after function invocation substitution, every constructor call
154
- and full-expression in the *mem-initializer*s would be a constant
155
- expression (including conversions), the program is ill-formed; no
156
- diagnostic required.
157
 
158
  ``` cpp
159
  constexpr int f(bool b)
160
  { return b ? throw 0 : 0; } // OK
161
- constexpr int f() { throw 0; } // ill-formed, no diagnostic required
162
 
163
  struct B {
164
  constexpr B(int x) : i(0) { } // x is unused
165
  int i;
166
  };
@@ -174,37 +142,25 @@ struct D : B {
174
  ```
175
 
176
  If the instantiated template specialization of a `constexpr` function
177
  template or member function of a class template would fail to satisfy
178
  the requirements for a `constexpr` function or `constexpr` constructor,
179
- that specialization is not a `constexpr` function or `constexpr`
180
- constructor. If the function is a member function it will still be
181
- `const` as described below. If no specialization of the template would
182
- yield a `constexpr` function or `constexpr` constructor, the program is
183
- ill-formed; no diagnostic required.
 
184
 
185
  A call to a `constexpr` function produces the same result as a call to
186
  an equivalent non-`constexpr` function in all respects except that a
187
  call to a `constexpr` function can appear in a constant expression.
188
 
189
- A `constexpr` specifier for a non-static member function that is not a
190
- constructor declares that member function to be `const` (
191
- [[class.mfct.non-static]]). The `constexpr` specifier has no other
192
- effect on the function type. The keyword `const` is ignored if it
193
- appears in the *cv-qualifier-seq* of the function declarator of the
194
- declaration of such a member function. The class of which that function
195
- is a member shall be a literal type ([[basic.types]]).
196
 
197
  ``` cpp
198
- class debug_flag {
199
- public:
200
- explicit debug_flag(bool);
201
- constexpr bool is_on(); // error: debug_flag not
202
- // literal type
203
- private:
204
- bool flag;
205
- };
206
  constexpr int bar(int x, int y) // OK
207
  { return x + y + x*y; }
208
  // ...
209
  int bar(int x, int y) // error: redefinition of bar
210
  { return x * 2 + 3 * y; }
@@ -215,12 +171,12 @@ object as `const`. Such an object shall have literal type and shall be
215
  initialized. If it is initialized by a constructor call, that call shall
216
  be a constant expression ([[expr.const]]). Otherwise, or if a
217
  `constexpr` specifier is used in a reference declaration, every
218
  full-expression that appears in its initializer shall be a constant
219
  expression. Each implicit conversion used in converting the initializer
220
- expressions and each constructor call used for the initialization shall
221
- be one of those allowed in a constant expression ([[expr.const]]).
222
 
223
  ``` cpp
224
  struct pixel {
225
  int x, y;
226
  };
 
1
  ### The `constexpr` specifier <a id="dcl.constexpr">[[dcl.constexpr]]</a>
2
 
3
  The `constexpr` specifier shall be applied only to the definition of a
4
+ variable or variable template, the declaration of a function or function
5
+ template, or the declaration of a static data member of a literal type (
6
+ [[basic.types]]). If any declaration of a function, function template,
7
+ or variable template has a `constexpr` specifier, then all its
8
+ declarations shall contain the `constexpr` specifier. An explicit
9
+ specialization can differ from the template declaration with respect to
10
+ the `constexpr` specifier. Function parameters cannot be declared
11
+ `constexpr`.
12
 
13
  ``` cpp
14
+ constexpr void square(int &x); // OK: declaration
15
  constexpr int bufsz = 1024; // OK: definition
16
  constexpr struct pixel { // error: pixel is a type
17
  int x;
18
  int y;
19
  constexpr pixel(int); // OK: declaration
20
  };
21
  constexpr pixel::pixel(int a)
22
+ : x(a), y(x) // OK: definition
23
+ { square(x); }
24
  constexpr pixel small(2); // error: square not defined, so small(2)
25
  // not constant~([expr.const]) so constexpr not satisfied
26
 
27
+ constexpr void square(int &x) { // OK: definition
28
+ x *= x;
29
  }
30
  constexpr pixel large(4); // OK: square defined
31
  int next(constexpr int x) { // error: not for parameters
32
  return x + 1;
33
  }
 
46
 
47
  - it shall not be virtual ([[class.virtual]]);
48
  - its return type shall be a literal type;
49
  - each of its parameter types shall be a literal type;
50
  - its *function-body* shall be `= delete`, `= default`, or a
51
+ *compound-statement* that does not contain
52
+ - an *asm-definition*,
53
+ - a `goto` statement,
54
+ - a *try-block*, or
55
+ - a definition of a variable of non-literal type or of static or
56
+ thread storage duration or for which no initialization is performed.
 
 
 
 
 
 
 
 
 
 
57
 
58
  ``` cpp
59
  constexpr int square(int x)
60
  { return x * x; } // OK
61
  constexpr long long_max()
62
  { return 2147483647; } // OK
63
+ constexpr int abs(int x) {
64
+ if (x < 0)
65
+ x = -x;
66
+ return x; // OK
67
+ }
68
+ constexpr int first(int n) {
69
+ static int value = n; // error: variable has static storage duration
70
+ return value;
71
+ }
72
+ constexpr int uninit() {
73
+ int a; // error: variable is uninitialized
74
+ return a;
75
+ }
76
  constexpr int prev(int x)
77
+ { return --x; } // OK
78
+ constexpr int g(int x, int n) { // OK
79
  int r = 1;
80
  while (--n > 0) r *= x;
81
  return r;
82
  }
83
  ```
84
 
85
+ The definition of a `constexpr` constructor shall satisfy the following
 
 
86
  constraints:
87
 
88
  - the class shall not have any virtual base classes;
89
+ - each of the parameter types shall be a literal type;
90
  - its *function-body* shall not be a *function-try-block*;
 
 
91
 
92
+ In addition, either its *function-body* shall be `= delete`, or it shall
93
+ satisfy the following constraints:
94
 
95
+ - either its *function-body* shall be `= default`, or the
96
+ *compound-statement* of its *function-body* shall satisfy the
97
+ constraints for a *function-body* of a `constexpr` function;
98
+ - every non-variant non-static data member and base class sub-object
99
+ shall be initialized ([[class.base.init]]);
100
+ - if the class is a union having variant members ([[class.union]]),
101
+ exactly one of them shall be initialized;
102
+ - if the class is a union-like class, but is not a union, for each of
103
+ its anonymous union members having variant members, exactly one of
104
+ them shall be initialized;
105
+ - for a non-delegating constructor, every constructor selected to
106
+ initialize non-static data members and base class sub-objects shall be
107
+ a `constexpr` constructor;
108
+ - for a delegating constructor, the target constructor shall be a
109
+ `constexpr` constructor.
 
 
 
110
 
111
  ``` cpp
112
  struct Length {
113
+ constexpr explicit Length(int i = 0) : val(i) { }
114
  private:
115
  int val;
116
  };
117
  ```
118
 
119
+ For a non-template, non-defaulted `constexpr` function or a
120
+ non-template, non-defaulted, non-inheriting `constexpr` constructor, if
121
+ no argument values exist such that an invocation of the function or
122
+ constructor could be an evaluated subexpression of a core constant
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  expression ([[expr.const]]), the program is ill-formed; no diagnostic
124
+ required.
 
 
 
 
125
 
126
  ``` cpp
127
  constexpr int f(bool b)
128
  { return b ? throw 0 : 0; } // OK
129
+ constexpr int f() { return f(true); } // ill-formed, no diagnostic required
130
 
131
  struct B {
132
  constexpr B(int x) : i(0) { } // x is unused
133
  int i;
134
  };
 
142
  ```
143
 
144
  If the instantiated template specialization of a `constexpr` function
145
  template or member function of a class template would fail to satisfy
146
  the requirements for a `constexpr` function or `constexpr` constructor,
147
+ that specialization is still a `constexpr` function or `constexpr`
148
+ constructor, even though a call to such a function cannot appear in a
149
+ constant expression. If no specialization of the template would satisfy
150
+ the requirements for a `constexpr` function or `constexpr` constructor
151
+ when considered as a non-template function or constructor, the template
152
+ is ill-formed; no diagnostic required.
153
 
154
  A call to a `constexpr` function produces the same result as a call to
155
  an equivalent non-`constexpr` function in all respects except that a
156
  call to a `constexpr` function can appear in a constant expression.
157
 
158
+ The `constexpr` specifier has no effect on the type of a `constexpr`
159
+ function or a `constexpr` constructor.
 
 
 
 
 
160
 
161
  ``` cpp
 
 
 
 
 
 
 
 
162
  constexpr int bar(int x, int y) // OK
163
  { return x + y + x*y; }
164
  // ...
165
  int bar(int x, int y) // error: redefinition of bar
166
  { return x * 2 + 3 * y; }
 
171
  initialized. If it is initialized by a constructor call, that call shall
172
  be a constant expression ([[expr.const]]). Otherwise, or if a
173
  `constexpr` specifier is used in a reference declaration, every
174
  full-expression that appears in its initializer shall be a constant
175
  expression. Each implicit conversion used in converting the initializer
176
+ expressions and each constructor call used for the initialization is
177
+ part of such a full-expression.
178
 
179
  ``` cpp
180
  struct pixel {
181
  int x, y;
182
  };