Conditional function evaluation

Ok, this might be a stupid question, but I totally don't understand Chapter 12.1.6.2 - Conditional Evaluation on C ++ Constexpr Functions. This is a very short text.

A conditional branch that is not accepted in a constexpr function is not evaluated. This means it does not require a runtime estimate. For example:

constexpr int check(int i)
{
    return (low<=i && i<high) ? i : throw out_of_range();
}

constexpr int low = 0;
constexpr int high = 99;

// ...
constexpr int val = check(f(x,y,z));

      

You can imagine that the low and high configuration parameters are known at compile time but not at design time, and that f (x, y, z) computes some implementation-dependent value.

Source for context

I tried to run the code above to try and understand the explanation, but I am getting an error. Can anyone provide a clearer explanation?

Edit: I created a program for testing:

#include<iostream>
#include<stdexcept>

using namespace std;

constexpr int low = 0;
constexpr int high = 99;

constexpr int check(int i) {
    return (low<=i && i<high) ? i : throw out_of_range();
}

constexpr int f(int x, int y, int z) {
    return x*y*z;
}

int main() {
    constexpr int val = check(f(2,2,2));
    cout << val << '\n';
}

      

It won't run:

no matching function for call to 'std::out_of_range::out_of_range()' //I'm really surprised at this
     return (low<=i && i<high) ? i : throw out_of_range();
error: body of constexpr function 'constexpr int check(int)' not a return-statement
 }
error: 'constexpr int check(int)' called in a constant expression
  constexpr int val = check(f(2,2,2));

      

+3


source to share


1 answer


This means that the conditional branch in a constexpr function is allowed to use non-constant expressions (i.e. those that require run-time checking, such as throwing an exception), as long as that branch is not executed when the function is called in the constant context expressions.

So, call check

to initialize the variable constexpr

val

if the function arguments are constant expressions and the condition (low<=i && i<high)

is true.

If the arguments are not constants, the function call is not a constant expression and therefore cannot initialize the variable constexpr

.



If the condition is false, the function must accept a false branch, which must throw an exception, which requires a runtime estimate, so the function is not a constant expression and therefore cannot initialize a variable constexpr

.

When the argument is a constant expression, the compiler knows at compile time if the branch will be taken, since the condition true

can completely ignore the branch false

and does not complain that throwing exceptions is not possible at compile time.

When a function is called at runtime, it can have any arguments, and the branch false

can be accepted and throw

evaluated as for a normal (non-conferencing) function.

+7


source







All Articles