6

if you do this:

constexpr int LEN = 100; 

LEN variable defined as const without need of typing const keyword.
It also have static storage, without need to type static keyword.

From the other hand, if we do same in class:

struct A{ constexpr static int SIZE = 100; }; 

SIZE is still defined as const without need of typing const keyword,

However SIZE is not static data member.
You need to type static explicitly. If you don't there will be compilation error.

Question is:
What is the reason of need to explicitly type static?

0

3 Answers 3

3

static doesn't have same signification in both context :

  • for LEN, static means "only available in this compilation unit", so only internal linkage. It's a storage specifier
  • for A::SIZE, static means "it's a class member", so not bound to specific instances

constexpr in class context can refer to instance or class member or function, so compiler can't determine at your place if it's static or not, ie bound or not to a specific instance. It's same reasoning as const specifier. But, as you can imagine, it's a non-sense to have a non-static constexpr member, so it's forbidden. Example :

class A { int a; constexpr A(int value): a(value) {} // constexpr bound to a specific instance constexpr int getDouble() const { return a*2; } // constexpr not bound to a specific instance static constexpr int getDouble(int b) { return b*2; } } 

constexpr in global context refers to something which will be calculated at compile time (or, for function, if not possible to calculate at compile time, which will be inlined), so no need of external linkage and so, comparable behavior as a static global variable or function (only comparable because, with compile time calculation or inlining, you also don't need internal linkage)

constexpr int a = 5; // Will be replace everywhere by value /* If b is constexpr, calcul are done at compile time and result will be used * else double is inlined, so no need of linkage at all */ constexpr int getDouble(int b) { return b * 2; } 
Sign up to request clarification or add additional context in comments.

1 Comment

You can't call a function "double" (it's a keyword) and you can't have non-static constexpr data members in a class.
1

constexpr should not imply static, because having constexpr without static makes sense. Consider:

#include <iostream> struct Dim { constexpr Dim(int a,int b) : a(a), b(b) {} constexpr int Prod() const { return a*b; } int a,b; }; int main() { constexpr Dim sz(3,4); int arr[ sz.Prod() ]; std::cout << sizeof(arr) << std::endl; } 

It should also not imply static outside of class definition since static there means 'local to translation unit' and constexpr does not require that.

3 Comments

At namespace scope, constexpr doesn't quite imply static, but it comes close. It implies const, and namespace-scope non-volatile const variables have internal linkage (i.e., are static) by default.
can you have volatile const variables?
@soandos: sure, you are not allowed to change them, but the program need to read them every time, since the hardware might change the value. (for example)
0

I think you are confused about what static means at global scope, and your question is based on that misunderstanding.

LEN variable defined as const without need of typing const keyword.

Of course constexpr implies const, that shouldn't be surprising.

It also have static storage, without need to type static keyword.

N.B. a global variable always has static storage, because its lifetime is global. Adding the static keyword does not change that, what it does is give it internal linkage meaning it is not accessible by name outside the current translation unit.

That's the same rule for constexpr and const on global variables: a namespace-scope const variable implicitly has internal linkage (which is one of the many meanings of "static").

But a class-scope const variable does not have internal linkage, even if you add static to it. Marking a variable static means something completely different at namespace-scope and class-scope. It doesn't make sense to automatically add static to class members marked const or constexpr because that would mean something completely different than it does to variables at namespace-scope.

So constexpr implies const (obviously), and at namespace scope const implies internal linkage.

At class scope constexpr still implies const, but that doesn't have any effect on whether a member variable is a "class variable" or an "instance variable".

1 Comment

downvoted, his question although badly phrased makes sense. If something is constexpr member (initialized at compile time and known at compile time) it makes no sense to make it an instance variable instead of class variable. Since it is idiotic to have instances store same value that never changes. In fact if you miss static code will not compile(meaning it has no other meaning): error: non-static data member 'SIZE' declared 'constexpr' constexpr int SIZE = 100;

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.