Files
cppdraft_translate/cppdraft/dcl/constexpr.md
2025-10-25 03:02:53 +03:00

137 lines
6.2 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[dcl.constexpr]
# 9 Declarations [[dcl]](./#dcl)
## 9.2 Specifiers [[dcl.spec]](dcl.spec#dcl.constexpr)
### 9.2.6 The constexpr and consteval specifiers [dcl.constexpr]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L887)
The constexpr specifier shall be applied only to
the definition of a variable or variable template,
a structured binding declaration, or
the declaration of a function or function template[.](#1.sentence-1)
The consteval specifier shall be applied only to
the declaration of a function or function template[.](#1.sentence-2)
A function or static data member
declared with the constexpr or consteval specifier
on its first declaration
is implicitly an inline function or variable ([[dcl.inline]](dcl.inline "9.2.8The inline specifier"))[.](#1.sentence-3)
If any declaration of a function or function template has
a constexpr or consteval specifier,
then all its declarations shall contain the same specifier[.](#1.sentence-4)
[*Note [1](#note-1)*:
An explicit specialization can differ from the template declaration
with respect to the constexpr or consteval specifier[.](#1.sentence-5)
— *end note*]
[*Note [2](#note-2)*:
Function parameters cannot be declared constexpr[.](#1.sentence-6)
— *end note*]
[*Example [1](#example-1)*: constexpr void square(int &x); // OK, declarationconstexpr int bufsz = 1024; // OK, definitionconstexpr struct pixel { // error: pixel is a typeint x; int y; constexpr pixel(int); // OK, declaration};constexpr pixel::pixel(int a): x(a), y(x) // OK, definition{ square(x); }constexpr pixel small(2); // error: square not defined, so small(2)// not constant ([[expr.const]](expr.const "7.7Constant expressions")) so constexpr not satisfiedconstexpr void square(int &x) { // OK, definition x *= x;}constexpr pixel large(4); // OK, square definedint next(constexpr int x) { // error: not for parametersreturn x + 1;}extern constexpr int memsz; // error: not a definition — *end example*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L934)
A constexpr or consteval specifier
used in the declaration of a function
declares that function to be
a [*constexpr function*](#def:specifier,constexpr,function "9.2.6The constexpr and consteval specifiers[dcl.constexpr]")[.](#2.sentence-1)
[*Note [3](#note-3)*:
A function or constructor declared with the consteval specifier
is an immediate function ([[expr.const]](expr.const "7.7Constant expressions"))[.](#2.sentence-2)
— *end note*]
A destructor, an allocation function, or a deallocation function
shall not be declared with the consteval specifier[.](#2.sentence-3)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L946)
A function is [*constexpr-suitable*](#def:constexpr-suitable "9.2.6The constexpr and consteval specifiers[dcl.constexpr]") if
it is not a coroutine ([[dcl.fct.def.coroutine]](dcl.fct.def.coroutine "9.6.4Coroutine definitions"))[.](#3.sentence-1)
Except for instantiated constexpr functions,
non-templated constexpr functions shall be constexpr-suitable[.](#3.sentence-2)
[*Example [2](#example-2)*: constexpr int square(int x){ return x * x; } // OKconstexpr long long_max(){ return 2147483647; } // OKconstexpr int abs(int x) {if (x < 0) x = -x; return x; // OK}constexpr int constant_non_42(int n) { // OKif (n == 42) {static int value = n; return value; }return n;}constexpr int uninit() {struct { int a; } s; return s.a; // error: uninitialized read of s.a}constexpr int prev(int x){ return --x; } // OKconstexpr int g(int x, int n) { // OKint r = 1; while (--n > 0) r *= x; return r;} — *end example*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L987)
An invocation of a constexpr function in a given context
produces the same result as
an invocation of an equivalent non-constexpr function in the same context
in all respects except that
- [(4.1)](#4.1)
an invocation of a constexpr function
can appear in a constant expression ([[expr.const]](expr.const "7.7Constant expressions")) and
- [(4.2)](#4.2)
copy elision is not performed in a constant expression ([[class.copy.elision]](class.copy.elision "11.9.6Copy/move elision"))[.](#4.sentence-1)
[*Note [4](#note-4)*:
Declaring a function constexpr can change whether an expression
is a constant expression[.](#4.sentence-2)
This can indirectly cause calls to std::is_constant_evaluated within an invocation of the function to produce a different value[.](#4.sentence-3)
— *end note*]
[*Note [5](#note-5)*:
It is possible to write a constexpr function for which
no invocation satisfies the requirements of a core constant expression[.](#4.sentence-4)
— *end note*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L1010)
The constexpr and consteval specifiers have no
effect on the type of a constexpr function[.](#5.sentence-1)
[*Example [3](#example-3)*: constexpr int bar(int x, int y) // OK{ return x + y + x*y; }// ...int bar(int x, int y) // error: redefinition of bar{ return x * 2 + 3 * y; } — *end example*]
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L1023)
A constexpr specifier used in an object declaration
declares the object as const[.](#6.sentence-1)
Such an object
shall have literal type and
shall be initialized[.](#6.sentence-2)
A constexpr variable shall be constant-initializable ([[expr.const]](expr.const "7.7Constant expressions"))[.](#6.sentence-3)
A constexpr variable that is an object,
as well as any temporary to which a constexpr reference is bound,
shall have constant destruction[.](#6.sentence-4)
[*Example [4](#example-4)*: struct pixel {int x, y;};constexpr pixel ur = { 1294, 1024 }; // OKconstexpr pixel origin; // error: initializer missingnamespace N {void f() {int x; constexpr int& ar = x; // OKstatic constexpr int& sr = x; // error: x is not constexpr-representable// at the point indicated below}// immediate scope here is that of N} — *end example*]