Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializing a constexpr with a const, -- int vs float

Tags:

c++

constexpr

I'm wondering why the integer ii is initiallized at compile time, but not the float ff here:

int main() {
  const int i = 1;
  constexpr int ii = i;

  const float f = 1.0;
  constexpr float ff = f;
 }

This is what happens when I try to compile:

> g++ -std=c++11 test.cc
test.cc: In function ‘int main()’:
test.cc:6:24: error: the value of ‘f’ is not usable in a constant expression
   constexpr float ff = f;
                        ^
test.cc:5:15: note: ‘f’ was not declared ‘constexpr’
   const float f = 1.0;
like image 942
Don Slowik Avatar asked Jan 07 '16 21:01

Don Slowik


People also ask

Should I use const or constexpr?

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 .

Why is constexpr over const?

const applies for variables, and prevents them from being modified in your code. constexpr tells the compiler that this expression results in a compile time constant value, so it can be used in places like array lengths, assigning to const variables, etc.

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. So, what does constexpr mean?

Is constexpr implicitly const?

In C++11, constexpr member functions are implicitly const.


2 Answers

Constant variables of integral types with constant initializers are integral constant expressions (de facto implicitely constexpr; see expr.const in ISO C++). float is not an integral type and does not meet the requirements for constant expression without the use of constexpr. (A similar case is why int can be but float cannot be a template parameter.)

like image 93
StenSoft Avatar answered Nov 15 '22 04:11

StenSoft


In C++ constant integers are treated differently than other constant types. If they are initialized with a compile-time constant expression they can be used in a compile time expression. This was done so that array size could be a const int instead of #defined (like you were forced in C):

(Assume no VLA extensions)

const int s = 10;
int a[s];          // OK in C++
like image 22
bolov Avatar answered Nov 15 '22 03:11

bolov