C++17 constexpr char

This code gives the following compile-time error:
>g++ -std=c++17 main2.cpp -o main2
main2.cpp: In function 'constexpr char func(char)':
main2.cpp:5:28: error: 'ch' is not a constant expression
     if constexpr (ch >= 'A')


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>

constexpr char func(char ch)
{
    if constexpr (ch >= 'A')
    {
        return ch - 1;
    }
    else
    {
        return ch;   
    }
}

int main()
{
    func('A');
}


>g++ --version
g++ (GCC) 7.1.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Is my compiler just too old, or am I doing illicit things?
Edit: Please note the actual logic in the code is contrived, it's not doing anything useful.

If I make it be "constexpr char ch" I get the error
main2.cpp:3:36: error: a parameter cannot be declared 'constexpr'
 constexpr char func(constexpr char ch)


What I'm trying to do is to get some char-related calculations to be calculated at compile-time, for fun, preferably without having to use template-metaprogramming.
Last edited on
The constexpr function may be called with an expression that is not a compile-time constant.

This is fine: constexpr char func( char ch ) { return ch >= 'A' ? ch-1 : ch ; }

C++20 has consteval: https://en.cppreference.com/w/cpp/language/consteval
So basically, the "constexpr if" inside the function was stricter than constexpr signature of the function. (I thought that restriction was alleviated in C++17, guess not.)

Thanks, I'll use the ternary operator for now.

Edit: And yeah, I understand that constexpr doesn't mean "has to be evaluated at compile time". Using templates or switch statements should enforce that, because case statements have to be known at compile-time, right?

And does that mean that "constexpr if" has to be a compile-time constant, being stricter than constexpr functions?
Last edited on
> does that mean that "constexpr if" has to be a compile-time constant,
> being stricter than constexpr functions?

Yes.

constexpr function: the function may be valid in a context requiring a constant-expression.
constexpr if: the condition must be a constant-expression.


> Using templates or switch statements should enforce that,
> because case statements have to be known at compile-time, right?

Yes. For example:
1
2
3
4
5
template < char CH > constexpr int foo()
{
    if constexpr( CH >= '0' && CH <= '9' ) return '9' - CH ;
    else return -1 ;
}
Very clear, thank you.
Topic archived. No new replies allowed.