Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why constexpr data members are not implicitly static?

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?

like image 446
Nick Avatar asked Mar 17 '16 09:03

Nick


2 Answers

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;     }
like image 174
Garf365 Avatar answered Oct 16 '22 22:10

Garf365


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.

like image 30
sp2danny Avatar answered Oct 16 '22 22:10

sp2danny