{"id":6300,"date":"2022-02-04T12:26:32","date_gmt":"2022-02-04T12:26:32","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/constexpr-and-consteval-functions-in-c-20\/"},"modified":"2023-06-26T09:15:46","modified_gmt":"2023-06-26T09:15:46","slug":"constexpr-and-consteval-functions-in-c-20","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/constexpr-and-consteval-functions-in-c-20\/","title":{"rendered":"constexpr and consteval Functions in C++20"},"content":{"rendered":"<p>With C++20, <code>constexpr<\/code> became way more powerful. Additionally, we have&nbsp; <code>consteval<\/code> functions in C++20 that are quite similar to <code>constexpr<\/code> functions.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6297\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/02\/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\/02\/constexpr.png 904w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/02\/constexpr-300x186.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/02\/constexpr-768x476.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>Let me first describe a feature in C++20 that surprised me the most.<\/p>\n<h2><code>constexpr<\/code> Containers and Algorithms of the Standard Template Library<\/h2>\n<p>C++20 supports the <code>constexpr<\/code> containers<code> std::vector<\/code> and<code> std::string<\/code>, where <code>constexpr<\/code> means that the member functions of both containers can be applied at compile time. Additionally, more than<br \/><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/algorithm\">100 classical algorithms of the Standard Template Library<\/a> are declared as <code>constexpr<\/code>. Consequently, you can sort a <code>std::vector<\/code> of ints at compile time.<\/p>\n<p>Let&#8217;s see what this means:<\/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: #0099ff; font-style: italic;\">\/\/ constexprVector.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;algorithm&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;vector&gt;<\/span>\r\n\r\nconstexpr <span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">maxElement<\/span>() {\r\n    std<span style=\"color: #555555;\">::<\/span>vector myVec <span style=\"color: #555555;\">=<\/span> {<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">4<\/span>, <span style=\"color: #ff6600;\">3<\/span>};        <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>sort(myVec.begin(), myVec.end());\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> myVec.back();\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>  <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n\r\n    constexpr <span style=\"color: #007788; font-weight: bold;\">int<\/span> maxValue <span style=\"color: #555555;\">=<\/span> maxElement();\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"maxValue: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> maxValue <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n\r\n    constexpr <span style=\"color: #007788; font-weight: bold;\">int<\/span> maxValue2 <span style=\"color: #555555;\">=<\/span> [] {\r\n        std<span style=\"color: #555555;\">::<\/span>vector myVec <span style=\"color: #555555;\">=<\/span> {<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">4<\/span>, <span style=\"color: #ff6600;\">3<\/span>};    <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n        std<span style=\"color: #555555;\">::<\/span>sort(myVec.begin(), myVec.end()) ;\r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> myVec.back();\r\n    }(); \r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"maxValue2: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> maxValue2 <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The two containers <code>std::vector<\/code> (lines (1) and (2)) are sorted at compile time using <code>constexpr<\/code>-declared functions. In the first case, the function <code>maxElement<\/code> returns the last element of the vector<code> myVec<\/code>, which is its maximum value. In the second case, I use an immediately-invoked lambda that is declared<code> constexpr.<\/code> Here is the output of the program:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6298\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/02\/constexprVector.png\" alt=\"constexprVector\" width=\"150\" height=\"73\" style=\"display: block; margin-left: auto; margin-right: auto;\" \/><code><\/code><\/p>\n<p>The crucial idea for <code>constexpr<\/code> containers is transient allocation.<\/p>\n<\/p>\n<h3>Transient Allocation<\/h3>\n<p>Transient allocation means that memory allocated at compile time must also be released at compile time. Consequently, the compiler can detect a function&#8217;s mismatch of allocation and deallocation. The following example applies transient allocation.<\/p>\n<p>&nbsp;<\/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: 0px; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ transientAllocation.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;memory&gt;<\/span>\r\n\r\nconstexpr <span style=\"color: #006699; font-weight: bold;\">auto<\/span> <span style=\"color: #cc00ff;\">correctRelease<\/span>() {  \r\n     <span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">*<\/span> p <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">new<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span>[<span style=\"color: #ff6600;\">2020<\/span>];\r\n     <span style=\"color: #006699; font-weight: bold;\">delete<\/span> [] p;\r\n     <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #ff6600;\">2020<\/span>;\r\n}\r\n\r\nconstexpr <span style=\"color: #006699; font-weight: bold;\">auto<\/span> <span style=\"color: #cc00ff;\">forgottenRelease<\/span>() { <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">*<\/span> p <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">new<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span>[<span style=\"color: #ff6600;\">2020<\/span>];  \r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #ff6600;\">2020<\/span>;\r\n}\r\n\r\nconstexpr <span style=\"color: #006699; font-weight: bold;\">auto<\/span> <span style=\"color: #cc00ff;\">falseRelease<\/span>() {     <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">*<\/span> p <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">new<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span>[<span style=\"color: #ff6600;\">2020<\/span>];\r\n    <span style=\"color: #006699; font-weight: bold;\">delete<\/span> p;                      <em> <span style=\"color: #0099ff;\">\/\/ (2)<\/span><\/em>\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #ff6600;\">2020<\/span>;\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    constexpr <span style=\"color: #007788; font-weight: bold;\">int<\/span> res1 <span style=\"color: #555555;\">=<\/span> correctRelease();\r\n    constexpr <span style=\"color: #007788; font-weight: bold;\">int<\/span> res2 <span style=\"color: #555555;\">=<\/span> forgottenRelease();\r\n    constexpr <span style=\"color: #007788; font-weight: bold;\">int<\/span> res3 <span style=\"color: #555555;\">=<\/span> falseRelease();\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The minor program has two serious issues. First, the memory in the <code>constexpr<\/code> function<code> forgottenRelease<\/code> (line (1)) is not released. Second, the non-array deallocation (line 3) in the <code>constexpr<\/code> function <code>falseRelease<\/code> (line (3)) does not match the array allocation. Consequentially, the compilation fails.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6299\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/02\/transientAllocation.png\" alt=\"transientAllocation\" width=\"600\" height=\"169\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/02\/transientAllocation.png 1322w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/02\/transientAllocation-300x85.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/02\/transientAllocation-1024x289.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/02\/transientAllocation-768x217.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>With C++20, we got <code>consteval<\/code> functions that are pretty similar to <code>contexpr<\/code> functions.<\/p>\n<h2><code>consteval<\/code> Functions<\/h2>\n<p>Often developers are irritated because they don&#8217;t know if a<code> constexpr<\/code> function is executed at run time or compile time. Let&#8217;s consider the following code snippet.<\/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: 0px; line-height: 125%;\">constexpr <span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">constexprFunction<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span> arg) {\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> arg <span style=\"color: #555555;\">*<\/span> arg;\r\n}\r\n\r\nstatic_assert(constexprFunction(<span style=\"color: #ff6600;\">10<\/span>) <span style=\"color: #555555;\">==<\/span> <span style=\"color: #ff6600;\">100<\/span>);                     <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> arrayNewWithConstExpressiomFunction[constexprFunction(<span style=\"color: #ff6600;\">100<\/span>)]; <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\nconstexpr <span style=\"color: #007788; font-weight: bold;\">int<\/span> prod <span style=\"color: #555555;\">=<\/span> constexprFunction(<span style=\"color: #ff6600;\">100<\/span>);                     <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> a <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">100<\/span>;\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> runTime <span style=\"color: #555555;\">=<\/span> constexprFunction(a);                              <em><span style=\"color: #0099ff;\">\/\/ (4)<\/span><\/em>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> runTimeOrCompiletime <span style=\"color: #555555;\">=<\/span> constexprFunction(<span style=\"color: #ff6600;\">100<\/span>);               <span style=\"color: #0099ff; font-style: italic;\">\/\/ (5)<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p><code>constexprFunction<\/code> is, as its name suggests, a <code>constexpr<\/code> function.<\/p>\n<ol>\n<li>A constexpr function must run at compile time when used in a <code>constexpr<\/code> context, or the result is requested at compile time. line (1) and line (2) are <code>constexpr<\/code> contexts. Line (3), on the contrary, requires the function execution&nbsp; <code>constexprFuncion<\/code> on compile time.<\/li>\n<li>The call<code> constexprFunction(a)&nbsp;<\/code> (line 4) must be executed at run time because a is not a constant expression.<\/li>\n<li>Line 5 is an interesting case. There are no requirements for the function execution. Therefore, the call constexprFunction(100) (line 5) can be executed at run or compile times. From the C++ standard perspective, both are fine.<\/li>\n<\/ol>\n<p>In contrast to a <code>constexpr<\/code> function, a <code>consteval<\/code> function can only be executed at compile time.<\/p>\n<p><code>consteval<\/code> creates a so-called immediate function.<\/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%;\">consteval <span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">sqr<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span> n) {\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> n <span style=\"color: #555555;\">*<\/span> n;\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Each invocation of an immediate function creates a compile-time constant.&nbsp; <code>consteval<\/code> cannot be applied to destructors or functions that allocate or deallocate. A <code>consteval<\/code> function is as a <code>constexpr<\/code> function implicitly inline and has to fulfill the requirements for a <code>constexpr<\/code> function.<\/p>\n<p>The requirements of a <code>constexpr<\/code> function in C++14 and, therefore, a <code>consteval<\/code> function are:<\/p>\n<ul>\n<li>A <code>consteval<\/code> (<code>constexpr<\/code>) can\n<ul>\n<li>have conditional jump instructions or loop instructions.<\/li>\n<li>have more than one instruction.<\/li>\n<li>invoke constexpr functions. A <code>consteval<\/code> function can only invoke a <code>constexpr<\/code> function but not the other way around.<\/li>\n<li>use fundamental data types as variables that must be initialized with a constant expression.<\/li>\n<\/ul>\n<\/li>\n<li>A <code>consteval<\/code> (<code>constexpr<\/code>) function cannot\n<ul>\n<li>have static or<code> thread_local<\/code> data.<\/li>\n<li>have a try block nor a goto instruction.<\/li>\n<li>invoke or use non-<code>consteval<\/code> functions or non-<code>constexpr<\/code> data.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>There is one exciting use-case that <code>consteval<\/code> enables. You can initialize a local non-constant variable at compile time.<\/p>\n<p>&nbsp;<\/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: 0px; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ compileTimeInitializationLocal.cpp<\/span>\r\n\r\nconsteval <span style=\"color: #006699; font-weight: bold;\">auto<\/span> <span style=\"color: #cc00ff;\">doubleMe<\/span>(<span style=\"color: #006699; font-weight: bold;\">auto<\/span> val) {\r\n  <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #ff6600;\">2<\/span> <span style=\"color: #555555;\">*<\/span> val;\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<span style=\"color: #006699; font-weight: bold;\">auto<\/span> res <span style=\"color: #555555;\">=<\/span> doubleMe(<span style=\"color: #ff6600;\">1010<\/span>);  <em><span style=\"color: #0099ff;\">\/\/ (1)<\/span><\/em>\r\n<span style=\"color: #555555;\">++<\/span>res;                     <span style=\"color: #0099ff; font-style: italic;\">\/\/ 2021 (2)<\/span>\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The local <code>res<\/code> is initialized at compile time (line 1) and modified at run time (line 2). On the contrary, if the function <code>doubleMe<\/code> is declared as <code>constexpr<\/code>, it could be executed at run time.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>Before I dive into the new topic block design with templates, I want to present in the next post the C++17 feature<code> constexpr if. constexpr if&nbsp;<\/code>enables it to compile source code conditionally and can be used for nice tricks at compile time.<\/p>\n<p>&nbsp;<\/p>\n<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>With C++20, constexpr became way more powerful. Additionally, we have&nbsp; consteval functions in C++20 that are quite similar to constexpr functions.<\/p>\n","protected":false},"author":21,"featured_media":6297,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[376],"tags":[429,428],"class_list":["post-6300","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-templates","tag-consteval","tag-constexpr"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6300","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=6300"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6300\/revisions"}],"predecessor-version":[{"id":6683,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6300\/revisions\/6683"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/6297"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=6300"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=6300"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=6300"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}