0

I am learning constexpr and, for my understanding, constexpr tells the compiler to calculate functions during compile time instead of running time. I used the following code for testing but bumped into an error I really don't understand. Can you please explain why?

#include <iostream>
#include <array>
using namespace std;

constexpr int foo(int i)
{
    return i + 5;
}

int main()
{
    int i = 10;
    std::array<int, foo(5)> arr; // OK
    // But...
    std::array<int, foo(i)> arr1; // Error
}

The error is: the value of 'i' is not usable in a constant expression. Why? i is declared beforehand why does it have to be a const?

1 Answer 1

6

for my understanding constexpr tells the compiler to calculate functions during compile time instead of running time.

Not exactly: with constexpr the compiler can (not must) calculate function compile time. And the compiler do it when it's necessary and possible.

In case of

std::array<int, foo(5)> arr; // OK

it's necessary (because the second template argument of std::array must be known at compile time) and possible (because 5 is known at compile time).

But with

int i = 10;
std::array<int, foo(i)> arr1; // Error

it's necessary (std::array) but not possible (because i is a not-constant variable and the compiler can't use the i value compile time but only run time).

It's necessary but not possible, so the error.

But you can write

int i { 10 };
int j { foo(i) };

because it's not possible call foo(i) compile time but it isn't necessary (because j can be initialized run time). So foo(i) is called (supposedly) run time.

To compile the std::array using foo(i), you should define i as constexpr (or const)

constexpr int i { 10 };

so the compiler can use the value of i compile time.

Why? i is declared beforehand why does it have to be a const?

Short answer: because the C++11 standard say so.

Long answer: because, in this way, it's simpler to construct a compiler. If you want to use a value compile time, you can declare it as constexpr and the compiler check that it is never modified. It's (relatively) simple to do.

Otherwise, if you could use compile time the value of a not-constant variable, the compiler should follow the story of a variable to determine it's value when used in a constexpr function. In your toy example is simple, in real life would be a nightmare.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.