constexpr Functions
This post is a cross-post from www.ModernesCpp.com.
Today, I continue my story about programming at compile time. After template metaprogramming, the type-traits library, today's topic is constexpr functions in particular.
You may wonder why I write an additional post about constexpr. I have already written a few posts about constexpr in the last few years. Here is my motivation. First, I will show interesting similarities of constexpr functions and templates. Second, I want to write about the improved power of constexpr in C++20. And finally, I also discuss?consteval in C++20. When some theory is not detailed enough in my posts, I will refer to previous posts. Let's start with a short recap before I dive into the new topics.
A Short Recap
constexpr allows you to program at compile time with the typical C++-Syntax. Constant expressions with constexpr can have three forms.
Variables
constexpr double pi = 3.14;
Functions
constexpr functions in C++14 are quite comfortable. They can
User-defined types
The rules for constexpr functions or methods are quite simple. In short, I call both functions.
constexpr functions can only depend on functionality which is a constant expression. Being a constexpr function does not mean that the function is executed at compile time. It says, that the function has the potential to run at compile time. A constexpr function can also run a run time. It's often a question of the compiler and the optimization level if a constexpr function runs at compile time or runtime. There are two contexts in which a constexpr function func has to run at compile time.
Here is a small example of the theory. The program constexpr14.cpp calculates the greates common divisor of two numbers.
// constexpr14.cpp
#include <iostream>
constexpr auto gcd(int a, int b){
while (b != 0){
auto t= b;
b= a % b;
a= t;
}
return a;
}
int main(){
std::cout << '\n';
constexpr int i= gcd(11, 121); // (1)
int a= 11;
int b= 121;
int j= gcd(a, b); // (2)
std::cout << "gcd(11,121): " << i << '\n';
std::cout << "gcd(a,b): " << j << '\n';
std::cout << '\n';
}
Line (1) calculates the result i at compile time, and line (2) j at run time. The compiler would complain when I declare j as constexpr: constexpr int j = gcd(a, b). The problem would be that int's a, and b are not constant expressions.
The output of the program should not surprise you.
The surprise may start now. Let me show you the magic with the Compiler Explorer.
Line (1) in the program constexpr14.cpp boils down to the constant 11 in the following expression: mov DWORD PTR[rbp-4], 11 (line 33 in the screenshot). In contrast, line (2) is a function call: call gcd(int, int) (line 41 in the screenshot).
After this recap, let me continue with the similarities of constexpr functions and templates metaprogramming.
Template Metaprogramming
constexpr functions have a lot in common with template metaprogramming. If you are not familiar with template metaprogramming, my following three previous posts should give you an idea.
Here is the big picture comparing constexpr functions with template metaprogramming:
I want to add a few remarks to my table.
Admittedly, this comparison was quite concise. A pictural comparison of a metafunction (see Template Metaprogramming - How it Works) and a constexpr function should answer the open questions. Both functions calculate the factorial of a number.
领英推荐
?constexpr functions and templates have more in common.
Template Instantiation
Once more, when you want to know the details about template instantiation, read my previous post "Template Instantiation".?Let me only emphasize the crucial facts.
A template such as isSmaller is two times syntactically checked:
template<typename T>
bool isSmaller(T fir, T sec){
return fir < sec;
}
isSmaller(5, 10); // (1)
std::unordered_set<int> set1;
std::unordered_set<int> set2;
isSmaller(set1, set2); // (2)
constexpr functions are also two times checked for syntax.
constexpr auto gcd(int a, int b){
while (b != 0){
auto t= b;
b= a % b;
a= t;
}
return a;
}
constexpr int i= gcd(11, 121); // (1)
int a= 11;
int b= 121;
constexpr int j= gcd(a, b); // (2)
In the end, templates and constexpr functions are also quite similar regarding the visibility of their definition.
Visibility
When you instantiate a template, its definition must be visible. The same holds for constexpr function. When you invoke a constexpr function, its definition must be visible.
What's Next?
In the next post, I write about constexpr functions in C++20 and the C++20 keyword consteval.
?
Thanks a lot to my Patreon Supporters: Matt Braun, Roman Postanciuc, Tobias Zindl, Marko, G Prvulovic, Reinhold Dr?ge, Abernitzke, Frank Grimm, Sakib, Broeserl, António Pina, Sergey Agafyin, Андрей Бурмистров, Jake, GS, Lawton Shoemake, Animus24, Jozo Leko, John Breland, espkk, Louis St-Amour, Venkat Nandam, Jose Francisco, Douglas Tinkham, Kuchlong Kuchlong, Robert Blanch, Truels Wissneth, Kris Kafka, Mario Luoni, Neil Wang, Friedrich Huber, lennonli, Pramod Tikare Muralidhara, Peter Ware, Daniel Hufschl?ger, Red Trip, Alessandro Pezzato, Evangelos Denaxas, Bob Perry, Satish Vangipuram, Andi Ireland, Richard Ohnemus, Michael Dunsky, Leo Goodstadt, Eduardo Velasquez, John Wiederhirn, Yacob Cohen-Arazi, Florian Tischler, Robin Furness, Michael Young, Holger Detering, Haken Gedek, Bernd Mühlhaus, Challanger, Matthieu Bolt, Stephen Kelley, Kyle Dean, and Tusar Palauri.
Thanks in particular to Jon Hess, Lakshman, Christian Wittenhorst, Sherhy Pyton, Dendi Suhubdy, Sudhakar Belagurusamy, Richard Sargeant, Rusty Fleming, Ralf Abramowitsch, and John Nebel.
My special thanks to Embarcadero
My special thanks to PVS-Studio
?
Mentoring Program
My new mentoring program "Fundamentals for C++ Professionals" starts in April. Get more information here: https://bit.ly/MentoringProgramModernesCpp.
Seminars
I'm happy to give online seminars or face-to-face seminars worldwide. Please call me if you have any questions.
Bookable (Online)
German
Standard Seminars (English/German)
Here is a compilation of my standard seminars. These seminars are only meant to give you a first orientation.
New
Contact Me
Modernes C++