An attempt to create a member of a struct with constexpr attribute without being static result in a compiler error(see below). Why is that? for a single constant value will I have this value in memory until program is terminatted instead of just scope of struct? should I back to use a macro?
struct foo
{
constexpr int n = 10;
// ...
};
error: non-static data member cannot be constexpr; did you intend to make it static?
A constexpr variable must have static storage at some point, it's baked in when the program is compiled.
static defines the object's lifetime during execution; constexpr specifies that the object should be available during compilation. Compilation and execution are disjoint and discontiguous, both in time and space.
The constexpr function is executed in a context that is evaluated at compile time. This can be a static_assert expression, such as with the type-traits library or the initialization of a C-array.
constexpr functions are implicitly inline , but not implicitly static .
constexpr variables. The primary difference between const and constexpr variables is that the initialization of a const variable can be deferred until run time. A constexpr variable must be initialized at compile time. All constexpr variables are const. A variable can be declared with constexpr, if it has a literal type and is initialized.
If there are only these two effects of static on constexpr objects, I would use static per default: We typically do not need the guarantee of unique addresses for our constexpr objects. For mutable constexpr objects (class types with mutable members), there are obviously different semantics between local static and non-static constexpr objects.
If any declaration of a function or function template has a constexpr specifier, then every declaration must contain that specifier. A constexpr variable must satisfy the following requirements: its type must be a LiteralType. it must be immediately initialized.
static constexpr int const& x = 42; // constexpr reference to a const int object // (the object has static storage duration // due to life extension by a static reference) Even though try blocks and inline assembly are allowed in constexpr functions, throwing exceptions or executing the assembly is still disallowed in a constant expression.
I don't know the official rational. But surely it could lead to confusion. I, for one, can't see what it means for a non-static data member to be constexpr
. Are you able to do the following?
struct foo {
constexpr int n = 10;
constexpr foo() { }
constexpr foo(int n):n(n) { } // overwrite value of n
};
Or does it mean that the initializer must be constant always, i.e you are not allowed to write the above (because n
is not constant/could potentially non-constant) but allowed to say
foo f = { 10 };
The rule that constexpr int n
is simply ill-formed rather than being implicitly static
seems good to me, as its semantics would not be clear IMO.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With