Home > Mobile >  Should I always define a constexpr static data member outside of the class?
Should I always define a constexpr static data member outside of the class?

Time:10-06

Why a constexpr static data member needs to be defined outside of the class on C 11, C 14 but it doesn't need that requirement on c 17, 20 and above?

struct Array{
    int static constexpr sz_ = 5;
    int ar_[sz_]{};
};

//int constexpr Array::sz_; // needed on `C  11`, `C  14` but not needed for C  17, C  20

void foo(int const& x){

}

int main(){
    foo(Array::sz_);
}
  • So is this a change in the standard? or should I always define that member outside of the class?

CodePudding user response:

The wording of the question is very confusing. static constexpr members have to be defined inline since C 11:

If a static data member of LiteralType is declared constexpr, it must be initialized with an initializer in which every expression is a constant expression, right inside the class definition:

https://en.cppreference.com/w/cpp/language/static

Only when such members are ODR-used, a separate definition is required in C 11.

Since C 17, static constexpr members are implicitly inline, and thus no separate definition is required for ODR usage (although it could be provided).

CodePudding user response:

Should I always define a constexpr static data member outside of the class?

Always?! Only a Sith deals in absolutes.

C 17 made static constexpr variables implicitly inline (in the linkage sense, they always needed an in-class initializer). The out-of-class definition remains an optional but deprecated feature.

D.1 Redeclaration of static constexpr data members [depr.static_constexpr]

1 For compatibility with prior C International Standards, a constexpr static data member may be redundantly redeclared outside the class with no initializer. This usage is deprecated. [ Example:

struct A {
  static constexpr int n = 5;  // definition (declaration in C   2014)
};

constexpr int A::n;  // redundant declaration (definition in C   2014)

 — end example ]

It's still supported, so you don't have to go about updating all of your existing code bases today. But it may be removed in the future (three, six, maybe nine years from now?) So you won't be able to add a redundant declaration forever.

If you write a new piece of code that requires C 17 or newer, then there's no need to add this re-declaration out of some principle.

  • Related