{"id":6286,"date":"2022-01-26T11:14:47","date_gmt":"2022-01-26T11:14:47","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/constexprfunctions\/"},"modified":"2023-06-26T09:16:12","modified_gmt":"2023-06-26T09:16:12","slug":"constexprfunctions","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/constexprfunctions\/","title":{"rendered":"constexpr Functions"},"content":{"rendered":"<p>Today, I continue my story about programming at compile time. After template metaprogramming, the type-traits library, today&#8217;s topic is <code>constexpr<\/code> functions in particular.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6284\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/01\/constexpr.png\" alt=\"constexpr\" width=\"650\" height=\"403\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/01\/constexpr.png 904w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/01\/constexpr-300x186.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/01\/constexpr-768x476.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>You may wonder why I am writing an additional post about <code>constexpr<\/code>. I have already written a few posts about <code>constexpr<\/code> in the last few years. Here is my motivation. First, I will show exciting similarities of <code>constexpr<\/code> functions and templates. Second, I want to write about the improved power of <code>constexpr<\/code> in C++20. And finally, I also discuss&nbsp;<code>consteval<\/code> in C++20. When some theory is not detailed enough in my posts, I will refer to previous posts. Let&#8217;s start with a short recap before I dive into the new topics.<\/p>\n<h2>A Short Recap<\/h2>\n<p><code>constexpr<\/code> allows you to program at compile time with the typical C++-Syntax. Constant expressions with <code>constexpr<\/code> can have three forms.<\/p>\n<h4>Variables<\/h4>\n<ul>\n<ul>\n<li>are implicit <span style=\"font-family: courier new, courier;\">const.<\/span><\/li>\n<li style=\"margin: 0; line-height: 125%;\">have to be initialized by a constant expression.<\/li>\n<\/ul>\n<\/ul>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\">           constexpr <span style=\"color: #00aaaa;\">double<\/span> pi = <span style=\"color: #009999;\">3.14<\/span>;\r\n<\/pre>\n<\/div>\n<h4>Functions<\/h4>\n<p>constexpr functions in C++14 are pretty comfortable. They can<\/p>\n<ul>\n<li>invoke other <span style=\"font-family: courier new, courier;\">constexpr<\/span> functions.<\/li>\n<li>can have variables that have to be initialized by a constant expression.<\/li>\n<li>can have conditional expressions or loops.<\/li>\n<li>are implicit <span style=\"font-family: courier new, courier;\">inline.<\/span><\/li>\n<li>cannot have <span style=\"font-family: courier new, courier;\">static<\/span> or <span style=\"font-family: courier new, courier;\">thread_local<\/span> data.<\/li>\n<\/ul>\n<h4>User-defined types<\/h4>\n<ul>\n<li>have to have a constructor, which is a constant expression.<span style=\"font-family: courier new, courier;\"><\/span><\/li>\n<li>cannot have virtual functions<i>.<\/i><\/li>\n<li>cannot have a virtual base class.<\/li>\n<\/ul>\n<p>The rules for <span style=\"font-family: courier new, courier;\">constexpr<\/span> functions or methods are pretty simple. In short, I call both functions.<\/p>\n<p><span style=\"font-family: courier new, courier;\">constexpr<\/span> functions can only depend on functionality which is a constant expression. Being a <span style=\"font-family: courier new, courier;\">constexpr<\/span> 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 <span style=\"font-family: courier new, courier;\">constexpr<\/span> function can also run a run time. It&#8217;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 <span style=\"font-family: courier new, courier;\">constexpr<\/span> function <span style=\"font-family: courier new, courier;\">func<\/span> has to run at compile time.<\/p>\n<ol>\n<li>The <span style=\"font-family: courier new, courier;\">constexpr<\/span> function is executed in a context evaluated at compile time. This can be a <span style=\"font-family: courier new, courier;\">static_assert<\/span> expression, such as with the type-traits library or the initialization of a C-array.<\/li>\n<li>The value of a <span style=\"font-family: courier new, courier;\">constexpr<\/span> function is requested with <code>constexpr<\/code>: <span style=\"font-family: courier new, courier;\">constexpr auto res = func(5)<\/span>;<\/li>\n<\/ol>\n<p>Here is a small example of the theory. The program <span style=\"font-family: courier new, courier;\">constexpr14.cpp<\/span> calculates the greates common divisor of two numbers.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ constexpr14.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\nconstexpr <span style=\"color: #006699; font-weight: bold;\">auto<\/span> <span style=\"color: #cc00ff;\">gcd<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span> a, <span style=\"color: #007788; font-weight: bold;\">int<\/span> b){\r\n  <span style=\"color: #006699; font-weight: bold;\">while<\/span> (b <span style=\"color: #555555;\">!=<\/span> <span style=\"color: #ff6600;\">0<\/span>){\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> t<span style=\"color: #555555;\">=<\/span> b;\r\n    b<span style=\"color: #555555;\">=<\/span> a <span style=\"color: #555555;\">%<\/span> b;\r\n    a<span style=\"color: #555555;\">=<\/span> t;\r\n  }\r\n  <span style=\"color: #006699; font-weight: bold;\">return<\/span> a;\r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n  \r\n std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> '\\n';\r\n  \r\n  constexpr <span style=\"color: #007788; font-weight: bold;\">int<\/span> i<span style=\"color: #555555;\">=<\/span> gcd(<span style=\"color: #ff6600;\">11<\/span>,<span style=\"color: #ff6600;\"> 121<\/span>);     <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n  \r\n  <span style=\"color: #007788; font-weight: bold;\">int<\/span> a<span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">11<\/span>;\r\n  <span style=\"color: #007788; font-weight: bold;\">int<\/span> b<span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">121<\/span>;\r\n  <span style=\"color: #007788; font-weight: bold;\">int<\/span> j<span style=\"color: #555555;\">=<\/span> gcd(a, b);                  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"gcd(11,121): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> i <span style=\"color: #555555;\">&lt;&lt;<\/span> '\\n';\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"gcd(a,b): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> j <span style=\"color: #555555;\">&lt;&lt;<\/span> '\\n';\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> '\\n';\r\n \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Line (1) calculates the result<span style=\"font-family: courier new, courier;\"> i<\/span> at compile time, and line (2) <span style=\"font-family: courier new, courier;\">j<\/span> at run time. The compiler would complain when I declare j as constexpr: <span style=\"font-family: courier new, courier;\">constexpr int j = gcd(a, b)<\/span>. The problem would be that <span style=\"font-family: courier new, courier;\">int&#8217;<\/span>s <span style=\"font-family: courier new, courier;\">a<\/span> and <span style=\"font-family: courier new, courier;\">b<\/span> are not constant expressions.<\/p>\n<p>The output of the program should not surprise you.<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5617\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/constexpr14.png\" alt=\"constexpr14\" width=\"400\" height=\"242\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/constexpr14.png 347w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/constexpr14-300x182.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>The surprise may start now. Let me show you the magic with the <a href=\"https:\/\/godbolt.org\/\">Compiler Explorer.<\/a><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5185\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/godbolt.png\" alt=\"godbolt\" style=\"display: block; margin-left: auto; margin-right: auto;\" width=\"921\" height=\"231\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/godbolt.png 921w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/godbolt-300x75.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/godbolt-768x193.png 768w\" sizes=\"auto, (max-width: 921px) 100vw, 921px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>Line (1) in the program <span style=\"font-family: courier new, courier;\">constexpr14.cpp<\/span> boils down to the constant 11 in the following expression: <span style=\"font-family: courier new, courier;\">mov DWORD PTR[rbp-4], 11<\/span> (line 33 in the screenshot). In contrast, line (2) is a function call: <span style=\"font-family: courier new, courier;\">call gcd(int, int)<\/span> (line 41 in the screenshot).<\/p>\n<p>After this recap, let me continue with the similarities of <code>constexpr<\/code> functions and templates metaprogramming.<\/p>\n<\/p>\n<h2>Template Metaprogramming<\/h2>\n<p>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.<\/p>\n<ul>\n<li><a href=\"https:\/\/www.modernescpp.com\/index.php\/template-metaprogramming-a-introduction\">Template Metaprogramming &#8211; How it All Started<\/a><\/li>\n<li><a href=\"https:\/\/www.modernescpp.com\/index.php\/template-metaprogramming-how-it-works\">Template Metaprogramming &#8211; How it Works<\/a><\/li>\n<li><a href=\"https:\/\/www.modernescpp.com\/index.php\/template-metaprogramming-hybrid-programming\">Template Metaprogramming &#8211; Hybrid Programming<\/a><\/li>\n<\/ul>\n<p>Here is the big picture comparing <code>constexpr<\/code> functions with template metaprogramming:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6285\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/01\/comparisonConstexprTemplateMetaprogramming.png\" alt=\"TemplateMetaprogrammingVersusConstexprOld\" width=\"600\" height=\"179\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/01\/comparisonConstexprTemplateMetaprogramming.png 783w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/01\/comparisonConstexprTemplateMetaprogramming-300x90.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/01\/comparisonConstexprTemplateMetaprogramming-768x230.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/>I want to add a few remarks to my table.<\/p>\n<ul>\n<li>A template metaprogram runs at compile, but a <code>constexpr<\/code> function&nbsp;can run at compile time or runtime.<\/li>\n<li>Arguments of a template metaprogram can be types, non-types such as <code>int<\/code>, or templates.<\/li>\n<li>There is no state at compile time and, therefore, no modification. This means template metaprogramming is programming in a pure functional style. Here are the characteristics from the functional style perspective:\n<ul>\n<li>In template metaprogramming, you return a new value each time instead of modifying a value.<\/li>\n<li>Controlling a for a loop by incrementing a variable such as i is not possible at compile-time: <code>for (int i; i &lt;= 10; ++i)<\/code>. Template metaprogramming, therefore, replaces loops with recursion.<\/li>\n<li>In template metaprogramming, conditional execution is replaced by template specialization.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Admittedly, this comparison was relatively concise. A pictural comparison of a metafunction (see <a href=\"https:\/\/www.modernescpp.com\/index.php\/template-metaprogramming-how-it-works\">Template Metaprogramming &#8211; How it Works<\/a><a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-programming-at-compile-time\">) <\/a>and a <span style=\"font-family: courier new, courier;\">constexpr<\/span> function should answer the open questions. Both functions calculate the factorial of a number.<\/p>\n<ul>\n<li>The function arguments of a<span style=\"font-family: courier new, courier;\"> constexpr<\/span> function correspond to template arguments of a metafunction.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5619\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison1.png\" alt=\"comparison1\" width=\"600\" height=\"283\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison1.png 1182w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison1-300x141.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison1-1024x483.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison1-768x362.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>&nbsp;A <span style=\"font-family: courier new, courier;\">constexpr<\/span> function can have variables and modify them. A metafunction generates a new value.<\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5620\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison2.png\" alt=\"comparison2\" width=\"600\" height=\"260\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison2.png 1189w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison2-300x130.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison2-1024x444.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison2-768x333.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<ul>\n<li>&nbsp;A metafunction uses recursion to simulate a loop.<\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5621\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison3.png\" alt=\"comparison3\" width=\"600\" height=\"262\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison3.png 1212w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison3-300x131.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison3-1024x448.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison3-768x336.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<ul>\n<li>Instead of an end condition, a metafunction uses a full specialization of a template to end a loop. Additionally, a metafunction uses partial or full specialization to perform conditional execution, such as if statements.<\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5622\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison4.png\" alt=\"comparison4\" width=\"600\" height=\"267\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison4.png 1199w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison4-300x134.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison4-1024x456.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison4-768x342.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<ul>\n<li>&nbsp;Instead of an updated value <span style=\"font-family: courier new, courier;\">res,<\/span> the metafunction generates in each iteration a new <span style=\"font-family: courier new, courier;\">value.<\/span>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5623\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison5.png\" alt=\"comparison5\" width=\"500\" height=\"226\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison5.png 1197w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison5-300x135.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison5-1024x462.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison5-768x346.png 768w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>A metafunction has no return statement. It uses the value as a return value.<\/li>\n<\/ul>\n<h3><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5624\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison6.png\" alt=\"comparison6\" width=\"600\" height=\"261\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison6.png 1210w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison6-300x130.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison6-1024x445.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/comparison6-768x334.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/h3>\n<p>&nbsp;constexpr functions and templates have more in common.<\/p>\n<h2>Template Instantiation<\/h2>\n<p>Once more, when you want to know the details about template instantiation, read my previous post, &#8220;<a href=\"https:\/\/www.modernescpp.com\/index.php\/template-instantiation\">Template Instantiation<\/a>&#8220;.&nbsp; Let me only emphasize the crucial facts.<\/p>\n<p>A template such as <code>isSmaller <\/code>is two times syntactically checked:<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">bool<\/span> isSmaller(T fir, T sec){\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> fir <span style=\"color: #555555;\">&lt;<\/span> sec;\r\n}\r\n\r\nisSmaller(<span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #ff6600;\">10<\/span>);       <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n\r\nstd<span style=\"color: #555555;\">::<\/span>unordered_set<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> set1;\r\nstd<span style=\"color: #555555;\">::<\/span>unordered_set<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> set2;\r\nisSmaller(set1, set2);  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<ul>\n<li>First, the syntax of the template definition is checked. This check is not required but allowed and typically done by compilers.<\/li>\n<li>Second, the compiler deduces the template arguments from the function arguments. It creates in this process for each template argument a concrete function and checks its syntax. This instantiation process fails in the case of<code> std::unordered_set&lt;int<\/code>&gt; (2) because the data type does not support the &lt; operator.<\/li>\n<\/ul>\n<p><code>constexpr<\/code> functions are also two times checked for syntax.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\">constexpr <span style=\"color: #006699; font-weight: bold;\">auto<\/span> <span style=\"color: #cc00ff;\">gcd<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span> a, <span style=\"color: #007788; font-weight: bold;\">int<\/span> b){\r\n  <span style=\"color: #006699; font-weight: bold;\">while<\/span> (b <span style=\"color: #555555;\">!=<\/span> <span style=\"color: #ff6600;\">0<\/span>){\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> t<span style=\"color: #555555;\">=<\/span> b;\r\n    b<span style=\"color: #555555;\">=<\/span> a <span style=\"color: #555555;\">%<\/span> b;\r\n    a<span style=\"color: #555555;\">=<\/span> t;\r\n  }\r\n  <span style=\"color: #006699; font-weight: bold;\">return<\/span> a;\r\n}\r\n\r\n\r\nconstexpr <span style=\"color: #007788; font-weight: bold;\">int<\/span> i<span style=\"color: #555555;\">=<\/span> gcd(<span style=\"color: #ff6600;\">11<\/span>,<span style=\"color: #ff6600;\"> 121<\/span>);     <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n  \r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> a<span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">11<\/span>;\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> b<span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">121<\/span>;<br \/>constexpr <span style=\"color: #007788; font-weight: bold;\">int<\/span> j<span style=\"color: #555555;\">=<\/span> gcd(a, b);        <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<ul>\n<li>First, the compiler checks if the function <code>gcd<\/code> can run at compile time. This means, essentially, that all dependencies of a constexpr function, such as the invoked function, must be <code>constexpr<\/code>.<\/li>\n<li>The compiler has to check for each invocation of <code>gcd<\/code> that the arguments are constant expressions. Consequentially, the first call (1) is valid, but not the second on (2).<\/li>\n<\/ul>\n<p>In the end, templates and constexpr functions are also quite similar regarding the visibility of their definition.<\/p>\n<h2>Visibility<\/h2>\n<p>When you instantiate a template, its definition must be visible. The same holds for <code>constexpr<\/code> function. When you invoke a <code>constexpr<\/code> function, its definition must be visible.<\/p>\n<h2><code>What's Next?<\/code><\/h2>\n<p>In the next post, I will write about <code>constexpr<\/code> functions in C++20 and the C++20 keyword <code>consteval<\/code>.<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today, I continue my story about programming at compile time. After template metaprogramming, the type-traits library, today&#8217;s topic is constexpr functions in particular.<\/p>\n","protected":false},"author":21,"featured_media":6284,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[376],"tags":[428],"class_list":["post-6286","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-templates","tag-constexpr"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6286","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=6286"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6286\/revisions"}],"predecessor-version":[{"id":6684,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6286\/revisions\/6684"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/6284"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=6286"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=6286"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=6286"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}