Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are all constexpr variable implicitly inline?

I was playing around with auto template parameters and I was surprised that this code didn't compiled:

constexpr auto bar = 2;

template<auto& T>
struct Foo {
    auto operator()() const { return T; }
};

int main() {
    Foo<bar> b;
    b();
}

Visual Studio 15.7 (preview 4) spit out these errors:

error C2970: 'Foo': template parameter 'T': 'bar': an expression involving objects with internal linkage cannot be used as a non-type argument
 note: see declaration of 'Foo'
 note: see declaration of 'bar'
error C2440: 'specialization': cannot convert from 'int' to 'int &'
 note: see reference to class template instantiation 'Foo<0>' being compiled
error C2973: 'Foo': invalid template argument 'int'
 note: see declaration of 'Foo'

Then, after adding inline, the error got away!

constexpr inline auto bar = 2;

I thought constexpr variables were implicitly inline. Also, how does that affect the linkage of my variable bar?

like image 747
Guillaume Racicot Avatar asked Apr 19 '18 04:04

Guillaume Racicot


People also ask

Is constexpr implicitly static?

constexpr is a compile time feature, where inline/static are runtime features. The meaning of constexpr is more restricted than static. The meaning is that given a particular input value the return value is always the same, and the copiler ought to be able to work it out completely during compilation.

Is constexpr implicitly const?

A constexpr non- static member function isn't required to be implicitly const .

Why does constexpr need to be static?

A static constexpr variable has to be set at compilation, because its lifetime is the the whole program. Without the static keyword, the compiler isn't bound to set the value at compilation, and could decide to set it later.

Can a constexpr be changed?

Both const and constexpr mean that their values can't be changed after their initialization. So for example: const int x1=10; constexpr int x2=10; x1=20; // ERROR. Variable 'x1' can't be changed.


1 Answers

Are all constexpr variable implicitly inline?

No. Only constexpr functions and constexpr static data members are implicitly inline ([dcl.constexpr]/1).

Also, how does that affect the linkage of my variable bar?

A constexpr variable is const ([dcl.constexpr]/9). A non-inline const variable that is not explicitly declared extern has internal linkage ([basic.link]/3).

like image 117
cpplearner Avatar answered Nov 03 '22 03:11

cpplearner