{"id":3534,"date":"2019-09-10T20:30:40","date_gmt":"2019-09-10T18:30:40","guid":{"rendered":"https:\/\/mariusbancila.ro\/blog\/?p=3534"},"modified":"2020-05-08T11:46:43","modified_gmt":"2020-05-08T09:46:43","slug":"let-there-be-constants","status":"publish","type":"post","link":"https:\/\/mariusbancila.ro\/blog\/2019\/09\/10\/let-there-be-constants\/","title":{"rendered":"Let there be constants!"},"content":{"rendered":"<p>In the beginning, there was <tt>const<\/tt>. And people saw that <tt>const<\/tt> was good. And then the people said: let there be <tt>constexpr<\/tt>, and <tt>consteval<\/tt>, and <tt>constinit<\/tt>. And thus, starts this article about constant functions and variables in C++20, which I will try to keep short and concise. <\/p>\n<p><!-- more --><\/p>\n<h1>const<\/h1>\n<p><tt>const<\/tt> is a specifier that indicates that a global, local, or member variable or a function parameter cannot be modified after it is initialized. It can also be used to qualify a non-static member function; such a constant member function cannot modify the object state (unless the fields are declared <tt>mutable<\/tt>) and can only invoke other constant member functions. Such a function, however, is still evaluated at runtime.<\/p>\n<pre class=\"lang:c++ decode:true \" >class foo\r\n{\r\n   int value;\r\npublic:\r\n   foo(int const v) : value(v) {}\r\n\r\n   int get() const { return value; }\r\n};\r\n\r\nint main()\r\n{\r\n   int const fortyTwo = 42;\r\n   foo f(fortyTwo);\r\n   int n = f.get();\r\n}<\/pre>\n<p>The term <em>const correctness<\/em> refers to using constants whereever is possible. However, the exact placement of the <tt>const<\/tt> specifier has generated a great debate within the C++ community between those that advocate the use of it on the left or right side of the type. These alternatives are called <em>East const<\/em> and <em>West const<\/em>.<\/p>\n<pre class=\"lang:c++ decode:true \" >int const a = 42;  \/\/ East const\r\nconst int a = 42;  \/\/ West const<\/pre>\n<p>I have been using East const for many years and I believe it&#8217;s the better alternative. I will not get into the details here, but you can read more about it here: <a href=\"https:\/\/mariusbancila.ro\/blog\/2018\/11\/23\/join-the-east-const-revolution\/\">Join the East const revolution!<\/a><\/p>\n<p>As of C++17, constants (and variables in general) can be declared <tt>inline<\/tt>. This makes it possible to define global constants in a header file, or initializing <tt>static<\/tt> <tt>const<\/tt> members of a class in a header, without risking to generate multiple definitions for the same symbol when the header is included in more than one translation unit.<\/p>\n<pre class=\"lang:c++ decode:true \" >\/\/ foo.h header\r\n\r\nstruct foo\r\n{\r\n   static const int alpha;\r\n};\r\n\r\ninline const int foo::alpha = 42;\r\n\r\ninline const int beta = 44;\r\n\r\nstruct bar\r\n{\r\n   inline static const int gamma = 42;\r\n};\r\n<\/pre>\n<h1>constexpr<\/h1>\n<p>The <tt>constexpr<\/tt> specifier was introduced in C++11 to indicate that a variable or function can appear in a constant expression, which is an expression that can be evaluated at compile time. <\/p>\n<pre class=\"lang:c++ decode:true \" >constexpr int maximum(int const a, int const b)\r\n{\r\n   return a &gt;= b ? a : b;\r\n}\r\n\r\nint main()\r\n{\r\n   int const Size = 64;\r\n   int arr[maximum(42, Size)]{ 0 };\r\n}<\/pre>\n<p>Specifying <tt>constexpr<\/tt> for a function does not mean that the function is always evaluated at compile-time. This is done only when it&#8217;s possible. If invoked with arguments that are not constant expressions, the evaluation will only happen at runtime, as shown in the following example.<\/p>\n<pre class=\"lang:c++ decode:true \" >\r\nconstexpr int m1 = maximum(42, 66);  \/\/ compile-time evaluation\r\nint a = 42, b = 66;\r\nconst int m2 = maximum(a, b);        \/\/ run-time evaluation<\/pre>\n<p>A <tt>constexpr<\/tt> specifier used in an object declaration implies <tt>const<\/tt>. A <tt>constexpr<\/tt> specifier used in a function or static member variable declaration implies <tt>inline<\/tt>.  If any declaration of a function or function template has a <tt>constexpr<\/tt> specifier, then every declaration must contain the specifier. <\/p>\n<p><tt>constexpr<\/tt> can be used not only with variables and functions, but also member functions, constructors, and as of C++20 with virtual functions. There are various other changes in C++20 related to <tt>constexpr<\/tt>:<\/p>\n<ul>\n<li>can use try-catch blocks in a <tt>constexpr<\/tt> function as long as no exception is thrown from the function;<\/li>\n<li>it is possible to change the active member of a union inside <tt>constexpr<\/tt>;<\/li>\n<li>it is possible to use <tt>dynamic_cast<\/tt> and polymorphic <tt>typeid<\/tt> in constant expressions;<\/li>\n<li><tt>std::string<\/tt>, <tt>std::vector<\/tt>, and other library types are <tt>constexpr<\/tt>;<\/li>\n<li><tt>std::is_constant_evaluated()<\/tt> added to allow to check if code is actually executed within a constant evaluation.<\/li>\n<\/ul>\n<h1>consteval<\/h1>\n<p>The <tt>consteval<\/tt> specifier is a new feature in C++20 that is used to specify that a function is an <em>immediate function<\/em>, which means that the function must always produce a constant expression. This has the implication that the function is only seen at compile time. Symbols are not emitted for the function, you cannot take the address of such a function, and tools such as debuggers will not be able to show them. In this matter, immediate functions are similar to macros.<\/p>\n<pre class=\"lang:c++ decode:true \" >consteval int maximum(int const a, int const b)\r\n{\r\n   return a &gt;= b ? a : b;\r\n} \r\n\r\nconstexpr int m1 = maximum(42, Size);   \/\/ OK, compile-time evaluation\r\nint a = 12, b = 66;\r\nconst int m2 = maximum(a, b);           \/\/ error\r\n\r\nusing fptr = int(int, int);\r\nfptr* pmax = maximum;                   \/\/ error\r\n<\/pre>\n<p>A <tt>consteval<\/tt> specifier implies <tt>inline<\/tt>. If any declaration of a function or function template contains a <tt>consteval<\/tt> specifier, then all declarations of that function or function template must contain the specifier. A function that is <tt>consteval<\/tt> is a <tt>constexpr<\/tt> function, and must satisfy the requirements applicable to <tt>constexpr<\/tt> functions (or <tt>constexpr<\/tt> constructors). <\/p>\n<h1>constinit<\/h1>\n<p>Before getting to the <tt>constinit<\/tt> specifier, let&#8217;s talk about initialization. There are various forms of initialization in C++. <em>Zero initialization<\/em> sets the initial value of an object to zero. It happens in several situations:<\/p>\n<pre class=\"lang:c++ decode:true \" >\/\/ 1\r\nstatic T object;\r\n\r\n\/\/ 2\r\nT ();\r\nT t = {};\r\nT {};\r\n\r\n\/\/ 3\r\nCharT array [ n ] = \"\";<\/pre>\n<p>Zero initialization is performed for every named variable with static or thread-local duration when constant-initialization does not happen and occurs before any other initialization. <\/p>\n<p><em>Constant initialization<\/em> sets the value of a static variable to a compile-time expression. It can have the following forms:<\/p>\n<pre class=\"lang:c++ decode:true \" >static T &amp; ref = constexpr;\r\nstatic T object = constexpr;<\/pre>\n<p>Constant initialization is performed instead of zero initialization. Together, zero-initialization and constant initialization are called <em>static initialization<\/em> and all other initialization is called <em>dynamic initialization<\/em>. All static initialization happens before any dynamic initialization.<\/p>\n<p>Variables with static storage duration that have dynamic initiliazation could cause bugs that are hard to find. Consider two static objects, A and B, initialized in different translation units. If the initialization of one of the objects, let&#8217;s say B, depends on the other object (for intance by invoking a member of that object), then the initialization may succeed, if the other object is already initialized, or fail, if the object is not initialized already. This result depends on the order of the initialization of the translation units, which is not deterministic.<\/p>\n<p>On the other hand, variables with static duration that have constant initialization are initialized at compile time and therefore can be safely used when performing dynamic initialization of translation units.<\/p>\n<p>The <tt>constinit<\/tt> specifier can be applied to variables with static storage duration and requires the variable to have a constant initializer. This specifier helps communicating the intention to both the compiler and other programmers. The specifier can be used on any declaration of a variable; however, if it is present on some declaration but not on the initializing declaration, the program is ill-formed.<\/p>\n<p>The following is an example from the <a href=\"http:\/\/open-std.org\/JTC1\/SC22\/WG21\/docs\/papers\/2019\/p1143r2.html\" target=\"_blank\" rel=\"noopener noreferrer\">P1143R2<\/a> paper.<\/p>\n<pre class=\"lang:c++ decode:true \" >char const * g() { return \"dynamic initialization\"; }\r\nconstexpr char const * f(bool p) { return p ? \"constant initializer\" : g(); }\r\n\r\nconstinit char const* c = f(true);   \/\/ OK.\r\nconstinit char const* d = f(false);  \/\/ ill-formed<\/pre>\n<h1>Keep in mind that&#8230;<\/h1>\n<p class=\"tip-lite\">\nAt most one of the <tt>constexpr<\/tt>, <tt>consteval<\/tt>, and <tt>constinit<\/tt> specifiers is allowed to appear within the same sequence of declaration specifiers.\n<\/p>\n<h1>See also<\/h2>\n<p>For more information about these topics see:<\/p>\n<ul>\n<li><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/constexpr\" target=\"_blank\" rel=\"noopener noreferrer\">constexpr specifier<\/a><\/li>\n<li><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/consteval\" target=\"_blank\" rel=\"noopener noreferrer\">consteval specifier<\/a><\/li>\n<li><a href=\"https:\/\/awfulcode.io\/2019\/01\/26\/immediate-functions-in-c20\/\" target=\"_blank\" rel=\"noopener noreferrer\">Immediate functions in C++20<\/a><\/li>\n<li><a href=\"https:\/\/herbsutter.com\/category\/c\/\" target=\"_blank\" rel=\"noopener noreferrer\">Trip report: Summer ISO C++ standards meeting (Rapperswil)<\/a><\/li>\n<li><a href=\"https:\/\/isocpp.org\/wiki\/faq\/ctors#static-init-order\" target=\"_blank\" rel=\"noopener noreferrer\">What\u2019s the \u201cstatic initialization order \u2018fiasco\u2019 (problem)\u201d?<\/a><\/li>\n<li><a href=\"https:\/\/hackaday.com\/2019\/07\/30\/c20-is-feature-complete-heres-what-changes-are-coming\/\" target=\"_blank\" rel=\"noopener noreferrer\">C++20 Is Feature Complete; Here\u2019s What Changes Are Coming<\/a><\/li>\n<li><a href=\"https:\/\/pabloariasal.github.io\/2019\/02\/28\/cpp-inlining\/\" target=\"_blank\" rel=\"noopener noreferrer\">C++ &#8211; Breaking The Rules With Inline Variables and Functions<\/a><\/li>\n<li><a href=\"https:\/\/www.fluentcpp.com\/2019\/07\/23\/how-to-define-a-global-constant-in-cpp\/\" target=\"_blank\" rel=\"noopener noreferrer\">What Every C++ Developer Should Know to (Correctly) Define Global Constants<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>In the beginning, there was <tt>const<\/tt>. And people saw that <tt>const<\/tt> was good. And then the people said: let there be <tt>constexpr<\/tt>, and <tt>consteval<\/tt>, and <tt>constinit<\/tt>. And thus, starts this article about constant functions and variables in C++20, which I will try to keep short and concise. <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","advgb_blocks_editor_width":"","advgb_blocks_columns_visual_guide":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[7],"tags":[451,543,570,606,604,605],"class_list":["post-3534","post","type-post","status-publish","format-standard","hentry","category-c","tag-c","tag-c20","tag-const","tag-consteval","tag-constexpr","tag-constinit"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.4 - aioseo.com -->\n\t<meta name=\"description\" content=\"This article summarizes the use of const, constexpr, consteval, and constinit in C++20.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Marius Bancila\"\/>\n\t<meta name=\"keywords\" content=\"c++,c++20,const,constexpr,constinit,consteval\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/mariusbancila.ro\/blog\/2019\/09\/10\/let-there-be-constants\/\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Marius Bancila&#039;s Blog | About code. Mostly on C++\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Let there be constants!\" \/>\n\t\t<meta property=\"og:description\" content=\"This article summarizes the use of const, constexpr, consteval, and constinit in C++20.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/mariusbancila.ro\/blog\/2019\/09\/10\/let-there-be-constants\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-09-10T18:30:40+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-05-08T09:46:43+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Let there be constants!\" \/>\n\t\t<meta name=\"twitter:description\" content=\"This article summarizes the use of const, constexpr, consteval, and constinit in C++20.\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2019\\\/09\\\/10\\\/let-there-be-constants\\\/#article\",\"name\":\"Let there be constants!\",\"headline\":\"Let there be constants!\",\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"},\"datePublished\":\"2019-09-10T20:30:40+02:00\",\"dateModified\":\"2020-05-08T11:46:43+02:00\",\"inLanguage\":\"en-US\",\"commentCount\":7,\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2019\\\/09\\\/10\\\/let-there-be-constants\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2019\\\/09\\\/10\\\/let-there-be-constants\\\/#webpage\"},\"articleSection\":\"C++, C++, c++20, const, consteval, constexpr, constinit\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2019\\\/09\\\/10\\\/let-there-be-constants\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"position\":2,\"name\":\"IT\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"position\":3,\"name\":\"Software\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"name\":\"C++\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"position\":4,\"name\":\"C++\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2019\\\/09\\\/10\\\/let-there-be-constants\\\/#listItem\",\"name\":\"Let there be constants!\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2019\\\/09\\\/10\\\/let-there-be-constants\\\/#listItem\",\"position\":5,\"name\":\"Let there be constants!\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"name\":\"C++\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/\",\"name\":\"Marius Bancila\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2019\\\/09\\\/10\\\/let-there-be-constants\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Marius Bancila\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2019\\\/09\\\/10\\\/let-there-be-constants\\\/#webpage\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2019\\\/09\\\/10\\\/let-there-be-constants\\\/\",\"name\":\"Let there be constants!\",\"description\":\"This article summarizes the use of const, constexpr, consteval, and constinit in C++20.\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2019\\\/09\\\/10\\\/let-there-be-constants\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"datePublished\":\"2019-09-10T20:30:40+02:00\",\"dateModified\":\"2020-05-08T11:46:43+02:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Let there be constants!","description":"This article summarizes the use of const, constexpr, consteval, and constinit in C++20.","canonical_url":"https:\/\/mariusbancila.ro\/blog\/2019\/09\/10\/let-there-be-constants\/","robots":"max-image-preview:large","keywords":"c++,c++20,const,constexpr,constinit,consteval","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/mariusbancila.ro\/blog\/2019\/09\/10\/let-there-be-constants\/#article","name":"Let there be constants!","headline":"Let there be constants!","author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"},"datePublished":"2019-09-10T20:30:40+02:00","dateModified":"2020-05-08T11:46:43+02:00","inLanguage":"en-US","commentCount":7,"mainEntityOfPage":{"@id":"https:\/\/mariusbancila.ro\/blog\/2019\/09\/10\/let-there-be-constants\/#webpage"},"isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/2019\/09\/10\/let-there-be-constants\/#webpage"},"articleSection":"C++, C++, c++20, const, consteval, constexpr, constinit"},{"@type":"BreadcrumbList","@id":"https:\/\/mariusbancila.ro\/blog\/2019\/09\/10\/let-there-be-constants\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/#listItem","position":1,"name":"Home","item":"https:\/\/mariusbancila.ro\/blog\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","position":2,"name":"IT","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","position":3,"name":"Software","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","name":"C++"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","position":4,"name":"C++","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2019\/09\/10\/let-there-be-constants\/#listItem","name":"Let there be constants!"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2019\/09\/10\/let-there-be-constants\/#listItem","position":5,"name":"Let there be constants!","previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","name":"C++"}}]},{"@type":"Organization","@id":"https:\/\/mariusbancila.ro\/blog\/#organization","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","url":"https:\/\/mariusbancila.ro\/blog\/"},{"@type":"Person","@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author","url":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/","name":"Marius Bancila","image":{"@type":"ImageObject","@id":"https:\/\/mariusbancila.ro\/blog\/2019\/09\/10\/let-there-be-constants\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g","width":96,"height":96,"caption":"Marius Bancila"}},{"@type":"WebPage","@id":"https:\/\/mariusbancila.ro\/blog\/2019\/09\/10\/let-there-be-constants\/#webpage","url":"https:\/\/mariusbancila.ro\/blog\/2019\/09\/10\/let-there-be-constants\/","name":"Let there be constants!","description":"This article summarizes the use of const, constexpr, consteval, and constinit in C++20.","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/mariusbancila.ro\/blog\/2019\/09\/10\/let-there-be-constants\/#breadcrumblist"},"author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"creator":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"datePublished":"2019-09-10T20:30:40+02:00","dateModified":"2020-05-08T11:46:43+02:00"},{"@type":"WebSite","@id":"https:\/\/mariusbancila.ro\/blog\/#website","url":"https:\/\/mariusbancila.ro\/blog\/","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","inLanguage":"en-US","publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"Marius Bancila's Blog | About code. Mostly on C++","og:type":"article","og:title":"Let there be constants!","og:description":"This article summarizes the use of const, constexpr, consteval, and constinit in C++20.","og:url":"https:\/\/mariusbancila.ro\/blog\/2019\/09\/10\/let-there-be-constants\/","article:published_time":"2019-09-10T18:30:40+00:00","article:modified_time":"2020-05-08T09:46:43+00:00","twitter:card":"summary","twitter:title":"Let there be constants!","twitter:description":"This article summarizes the use of const, constexpr, consteval, and constinit in C++20."},"aioseo_meta_data":{"post_id":"3534","title":"Let there be constants!","description":"This article summarizes the use of const, constexpr, consteval, and constinit in C++20.","keywords":[{"label":"C++","value":"C++"},{"label":"C++20","value":"C++20"},{"label":"const","value":"const"},{"label":"constexpr","value":"constexpr"},{"label":"constinit","value":"constinit"},{"label":"consteval","value":"consteval"}],"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":null,"created":"2021-03-18 21:03:35","updated":"2025-12-12 07:53:21","seo_analyzer_scan_date":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"author_meta":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"featured_img":null,"jetpack_publicize_connections":[],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"uagb_comment_info":7,"uagb_excerpt":"In the beginning, there was const. And people saw that const was good. And then the people said: let there be constexpr, and consteval, and constinit. And thus, starts this article about constant functions and variables in C++20, which I will try to keep short and concise.","coauthors":[],"tax_additional":{"categories":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">C++<\/span>"]},"tags":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">c++20<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">const<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">consteval<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">constexpr<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">constinit<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">C++<\/span>","<span class=\"advgb-post-tax-term\">c++20<\/span>","<span class=\"advgb-post-tax-term\">const<\/span>","<span class=\"advgb-post-tax-term\">consteval<\/span>","<span class=\"advgb-post-tax-term\">constexpr<\/span>","<span class=\"advgb-post-tax-term\">constinit<\/span>"]}},"comment_count":"7","relative_dates":{"created":"Posted 7 years ago","modified":"Updated 6 years ago"},"absolute_dates":{"created":"Posted on September 10, 2019","modified":"Updated on May 8, 2020"},"absolute_dates_time":{"created":"Posted on September 10, 2019 8:30 pm","modified":"Updated on May 8, 2020 11:46 am"},"featured_img_caption":"","series_order":"","jetpack_shortlink":"https:\/\/wp.me\/pYNdv-V0","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/3534","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/comments?post=3534"}],"version-history":[{"count":19,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/3534\/revisions"}],"predecessor-version":[{"id":3838,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/3534\/revisions\/3838"}],"wp:attachment":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/media?parent=3534"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/categories?post=3534"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/tags?post=3534"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}