Apollys supports Monica
Apollys supports Monica

Reputation: 3258

C++ constexpr - Value can be evaluated at compile time?

I was reading about constexpr here:

The constexpr specifier declares that it is possible to evaluate the value of the function or variable at compile time.

When I first read this sentence, it made perfect sense to me. However, recently I've come across some code that completely threw me off. I've reconstructed a simple example below:

#include <iostream>

void MysteryFunction(int *p);

constexpr int PlusOne(int input) {
  return input + 1;
}

int main() {
  int i = 0;
  MysteryFunction(&i);
  std::cout << PlusOne(i) << std::endl;

  return 0;
}

Looking at this code, there is no way for me to say what the result of PlusOne(i) should be, however it actually compiles! (Of course linking will fail, but g++ -std=c++11 -c succeeds without error.)

What would be the correct interpretation of "possible to evaluate the value of the function at compile time"?

Upvotes: 10

Views: 6261

Answers (4)

NoSenseEtAl
NoSenseEtAl

Reputation: 30048

All the answers are correct, but I want to give one short example that I use to explain how ridiculously unintuitive constexpr is.

#include <cstdlib>
constexpr int fun(int i){
    if (i==42){
        return 47;
    } else {
        return rand();
    }
}

int main()
{ 
    int arr[fun(42)];
}

As a side note: some people find constexpr status unsatisfying so they proposed constexpr! keyword addition to the language.

Upvotes: 4

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385194

The quoted wording is a little misleading in a sense. If you just take PlusOne in isolation, and observe its logic, and assume that the inputs are known at compile-time, then the calculations therein can also be performed at compile-time. Slapping the constexpr keyword on it ensures that we maintain this lovely state and everything's fine.

But if the input isn't known at compile-time then it's still just a normal function and will be called at runtime.

So the constexpr is a property of the function ("possible to evaluate at compile time" for some input, not for all input) not of your function/input combination in this specific case (so not for this particular input either).

It's a bit like how a function could take a const int& but that doesn't mean the original object had to be const. Here, similarly, constexpr adds constraints onto the function, without adding constraints onto the function's input.

Admittedly it's all a giant, confusing, nebulous mess (C++! Yay!). Just remember, your code describes the meaning of a program! It's not a direct recipe for machine instructions at different phases of compilation.

(To really enforce this you'd have the integer be a template argument.)

Upvotes: 14

R Sahu
R Sahu

Reputation: 206627

What would be the correct interpretation of "possible to evaluate the value of the function at compile time"?

If all the arguments to the function are evaluatable at compile time, then the return value of the function can be evaluated at compile time.

However, if the values of the arguments to the function are known only at run time, then the retun value of the function can only be evaluated at run time.

Hence, it possible to evaluate the value of the function at compile time but it is not a requirement.

Upvotes: 8

Brian Bi
Brian Bi

Reputation: 119239

A constexpr function may be called within a constant expression, provided that the other requirements for the evaluation of the constant expression are met. It may also be called within an expression that is not a constant expression, in which case it behaves the same as if it had not been declared with constexpr. As the code in your question demonstrates, the result of calling a constexpr function is not automatically a constant expression.

Upvotes: 12

Related Questions