C++20: consteval and constexpr functions

Optimizing compilers seek try to push as much of the computation as possible at compile time. In modern C++, you can declare a function as ‘constexpr’, meaning that you state explicitly that the function may be executed at compile time.

The constexpr qualifier is not magical. There may not be any practical difference in practice between an inline function and a constexpr function, as in this example:

inline int f(int x) {
  return x+1;
}

constexpr int fc(int x) {
  return x+1;
}

In both cases, the compiler may compute the result at compile time.

The fast_float C++ library allows you to parsing strings to floating-point numbers at compile time if your compiler supports C++20. Thus you can write the following function which returns either the parsed floating-point value or the number -1.0 in case of error:

constexpr double parse(std::string_view input) {
  double result;
  auto answer = fast_float::from_chars(input.data(),
    input.data()+input.size(), result);
  if(answer.ec != std::errc()) { return -1.0; }
  return result;
}

So what happens if you put parse("3.1416") in your code? Unfortunately, even at the highest optimization levels, you cannot be certain that the function will be computed at compile time.

Thankfully, C++20 has an another attribute ‘consteval’ which ensures that the function is evaluated at compile time:

consteval double parse(std::string_view input) {
  double result;
  auto answer = fast_float::from_chars(input.data(),
    input.data()+input.size(), result);
  if(answer.ec != std::errc()) { return -1.0; }
  return result;
}

What happens if the parameter of the function cannot be determined at compile time? There should be a compilation error.

With the consteval qualifier, the following two functions should be practically equivalent:

double f1() {
  return parse("3.1416");
}

double f2() {
  return 3.1416;
}

You can try it out with fast_float if you’d like.

Published by

Daniel Lemire

A computer science professor at the University of Quebec (TELUQ).

One thought on “C++20: consteval and constexpr functions”

Leave a Reply

Your email address will not be published.

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax

You may subscribe to this blog by email.