1

I'm trying to compare a function parameter inside a constexpr-if statement.

Here is a simple example:

constexpr bool test_int(const int i) {
  if constexpr(i == 5) { return true; }
 else { return false; }
}

However, when I compile this with GCC 7 with the following flags: g++-7 -std=c++1z test.cpp -o test I get the following error message:

test.cpp: In function 'constexpr bool test_int(int)':
test.cpp:3:21: error: 'i' is not a constant expression
 if constexpr(i == 5) { return true; }

However, if I replace test_int with a different function:

constexpr bool test_int_no_if(const int i) { return (i == 5); }

Then the following code compiles with no errors:

int main() {
  constexpr int i = 5;
  static_assert(test_int_no_if(i));
  return 0;
}

I don't understand why the constexpr-if version fails to compile, especially since the static_assert works just fine.

Any advice on this would be appreciated.

Thanks!

2
  • 2
    why constexpr(i == 5) and not just i==5? Commented Jul 28, 2017 at 15:34
  • any why so complicated? why not return i==5? Commented Jul 28, 2017 at 15:45

2 Answers 2

6

From constexpr if:

In a constexpr if statement, the value of condition must be a contextually converted constant expression of type bool.

Then, from constant expression:

Defines an expression that can be evaluated at compile time.

Obviously, i == 5 is not a constant expression, because i is a function parameter which is evaluated at run time. That is why the compiler complains.

When you use a function:

constexpr bool test_int_no_if(const int i) { return (i == 5); }

then it might be evaluated during the compile time depending on whether it's parameter is known at compile time or not.

If i is defined like:

constexpr int i = 5;

then the value of i is known during the compile time and test_int_no_if might be evaluated during the compile too making it possible to call it inside static_assert.

Also note, that marking function parameter as const does not make it a compile time constant. It just means that you cannot change the parameter inside the function.

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

Comments

2

A constexpr function can be called with non-constexpr arguments, in which case it behaves like a normal function, so the code must still compile as if it were not constexpr.

In short, there's nothing in test_int_no_if that depends on i being constexpr, while in test_int(), there is. ("constexpr if" only works with compile time expressions.)

1 Comment

This is the most useful answer IMHO

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.