{"id":5019,"date":"2016-11-06T06:14:06","date_gmt":"2016-11-06T06:14:06","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/the-null-pointer-constant-nullptr\/"},"modified":"2023-06-26T12:37:10","modified_gmt":"2023-06-26T12:37:10","slug":"the-null-pointer-constant-nullptr","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/the-null-pointer-constant-nullptr\/","title":{"rendered":"The Null Pointer Constant nullptr"},"content":{"rendered":"<p>The new null pointer nullptr cleans up in C++ with the ambiguity of 0 and the macro NULL.<\/p>\n<p><!--more--><\/p>\n<h2>The number 0<\/h2>\n<p>The issue with the literal 0 is that it can be the null pointer <span style=\"font-family: courier new,courier;\">(void*)0<\/span> or the number 0. This is up to the context. I admit we are used to this oddity. But only almost.<\/p>\n<p>Therefore, the small program with the number 0 should be confusing.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ null.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;typeinfo&gt;<\/span>\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n\r\n  std::cout &lt;&lt; std::endl;\r\n\r\n  <span style=\"color: #2b91af;\">int<\/span> a= 0;\r\n  <span style=\"color: #2b91af;\">int<\/span>* b= 0;\r\n  <span style=\"color: #0000ff;\">auto<\/span> c= 0;\r\n  <span style=\"color: #000000;\">std::cout &lt;&lt; typeid(c).name() &lt;&lt; std::endl;<\/span>\r\n\r\n  <span style=\"color: #0000ff;\">auto<\/span> res= a+b+c;\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"res: \"<\/span> &lt;&lt; res &lt;&lt; std::endl;\r\n  <span style=\"color: #000000;\">std::cout &lt;&lt; typeid(res).name() &lt;&lt; std::endl;<\/span>\r\n  \r\n  std::cout &lt;&lt; std::endl;\r\n\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The question is: What are the data type of variable <span style=\"font-family: courier new,courier;\">c<\/span> in line 12 and variable <span style=\"font-family: courier new,courier;\">res<\/span> in line 15?<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5014\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/null.png\" alt=\"null\" width=\"554\" height=\"215\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/null.png 554w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/null-300x116.png 300w\" sizes=\"auto, (max-width: 554px) 100vw, 554px\" \/><\/p>\n<p>The variable<span style=\"font-family: courier new,courier;\"> c<\/span> is of type <span style=\"font-family: courier new,courier;\">int<\/span>, and the variable <span style=\"font-family: courier new,courier;\">res<\/span> is of type pointer to <span style=\"font-family: courier new,courier;\">int: int*.<\/span> Pretty simple, right? The expression <span style=\"font-family: courier new,courier;\">a+b+c i<\/span>n line 15 is a pointer arithmetic.<\/p>\n<\/p>\n<h2>The macro NULL<\/h2>\n<p>The issue with the null pointer NULL is that it&nbsp;implicitly converts to <span style=\"font-family: courier new,courier;\">int.<\/span> Not so nice.<\/p>\n<p>According to<span style=\"font-family: courier new,courier;\"> <\/span><a href=\"http:\/\/en.cppreference.com\/w\/cpp\/types\/NULL\">en.cppreference.com&nbsp;<\/a>the macro NULL is an implementation-defined null pointer constant. A possible implementation:&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0000ff;\">#define NULL 0<\/span>\r\n<span style=\"color: #008000;\">\/\/since C++11<\/span>\r\n<span style=\"color: #0000ff;\">#define NULL nullptr<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>But that will not apply to my platform. Null seems to be of the type<span style=\"font-family: courier new,courier;\"> long int. <\/span>I will refer to this point later. The usage of the macro NULL raises some questions.<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ nullMacro.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;typeinfo&gt;<\/span>\r\n\r\nstd::string overloadTest(<span style=\"color: #2b91af;\">int<\/span>){\r\n  <span style=\"color: #0000ff;\">return<\/span> <span style=\"color: #a31515;\">\"int\"<\/span>;\r\n}\r\n\r\nstd::string overloadTest(<span style=\"color: #2b91af;\">long<\/span> <span style=\"color: #2b91af;\">int<\/span>){\r\n  <span style=\"color: #0000ff;\">return<\/span> <span style=\"color: #a31515;\">\"long int\"<\/span>;\r\n}\r\n\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n\r\n  std::cout &lt;&lt; std::endl;\r\n  \r\n  <span style=\"color: #2b91af;\">int<\/span> a= NULL;\r\n  <span style=\"color: #2b91af;\">int<\/span>* b= NULL;\r\n  <span style=\"color: #0000ff;\">auto<\/span> c= NULL;\r\n  <span style=\"color: #008000;\">\/\/ std::cout &lt;&lt; typeid(c).name() &lt;&lt; std::endl;<\/span>\r\n  <span style=\"color: #008000;\">\/\/ std::cout &lt;&lt; typeid(NULL).name() &lt;&lt; std::endl;<\/span>\r\n  \r\n  \r\n  <span style=\"color: #008000;\"><span style=\"color: #000000;\">std::cout &lt;&lt; \"overloadTest(NULL)= \" &lt;&lt; overloadTest(NULL) &lt;&lt; std::endl;<\/span><\/span>\r\n  \r\n  std::cout &lt;&lt; std::endl;\r\n\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The compiler complains about the implicit conversion to <span style=\"font-family: courier new,courier;\">int<\/span> in line 19. That&#8217;s ok. But the warning in line 21 is confusing. The compiler automatically deduces the type of the variable <span style=\"font-family: courier new,courier;\">c<\/span> to<span style=\"font-family: courier new,courier;\"> long int<\/span>. At the same time, it complains that the expression <span style=\"font-family: courier new,courier;\">NULL<\/span> must be converted. My observation is following the call <span style=\"font-family: courier new,courier;\">overloadTest(NULL)<\/span> in line 26. The compiler uses the version for the type <span style=\"font-family: courier new,courier;\">long int<\/span> (line 10). If the implementation uses <span style=\"font-family: courier new,courier;\">NULL<\/span> of type <span style=\"font-family: courier new,courier;\">int,<\/span> the compiler will choose <span style=\"font-family: courier new,courier;\">overloadTest<\/span> for the parameter type <span style=\"font-family: courier new,courier;\">int<\/span> (line 6). That is fine according to the C++ standard.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5015\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/nullMacro.png\" alt=\"nullMacro\" width=\"800\" height=\"210\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/nullMacro.png 1068w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/nullMacro-300x79.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/nullMacro-1024x269.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/nullMacro-768x202.png 768w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/p>\n<p>Now I want to know the current null pointer constant NULL type<span style=\"font-family: courier new,courier;\">.<\/span> Therefore, I comment on lines 22 and 23 of the program.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5016\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/nullMacroType.png\" alt=\"nullMacroType\" width=\"617\" height=\"216\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/nullMacroType.png 617w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/nullMacroType-300x105.png 300w\" sizes=\"auto, (max-width: 617px) 100vw, 617px\" \/><\/p>\n<p>NULL seems for the compiler on one hand of type <span style=\"font-family: courier new,courier;\">long int<\/span> and the other hand a constant pointer. This behavior shows&nbsp;the compilation of the program <span style=\"font-family: courier new,courier;\">nullMacro.cpp.<\/span><\/p>\n<p>I learned my lesson. Don&#8217;t use the macro NULL.<\/p>\n<p>But we have our rescue with the new null pointer constant <span style=\"font-family: courier new,courier;\">nullptr.<\/span><\/p>\n<h2>The null pointer constant nullptr<\/h2>\n<p>The new null pointer <span style=\"font-family: courier new,courier;\">nullptr<\/span> cleans up in C++ with the ambiguity of 0 and the macro NULL. nullptr is and remains of type <span style=\"font-family: courier new,courier;\">std::nullptr_t.<\/span><\/p>\n<p>You can assign arbitrary pointers to a <span style=\"font-family: courier new,courier;\">nullptr. <\/span>The pointer becomes a null pointer and points to no data. You can not dereference a <span style=\"font-family: courier new,courier;\">nullptr.<\/span> The pointer of this type can on the one hand compared with all pointers and can, on the other hand, converted to all pointers. This also holds true for pointers to class members. But you can not compare and convert a <span style=\"font-family: courier new,courier;\">nullptr<\/span> to an integral type. There is one exception to this&nbsp;rule. You can implicitly compare and convert a bool value with a <span style=\"font-family: courier new,courier;\">nullptr.<\/span> Therefore, you can use a <span style=\"font-family: courier new,courier;\">nullptr<\/span> in a logical expression.<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ nullptr.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;string&gt;<\/span>\r\n\r\nstd::string overloadTest(<span style=\"color: #2b91af;\">char<\/span>*){\r\n  <span style=\"color: #0000ff;\">return<\/span> <span style=\"color: #a31515;\">\"char*\"<\/span>;\r\n}\r\n\r\nstd::string overloadTest(<span style=\"color: #2b91af;\">long<\/span> <span style=\"color: #2b91af;\">int<\/span>){\r\n  <span style=\"color: #0000ff;\">return<\/span> <span style=\"color: #a31515;\">\"long int\"<\/span>;\r\n}\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n\r\n  std::cout &lt;&lt; std::endl;\r\n\r\n  <span style=\"color: #2b91af;\">long<\/span> <span style=\"color: #2b91af;\">int<\/span>* pi = nullptr;       \r\n  <span style=\"color: #008000;\">\/\/ long int i= nullptr;       \/\/ ERROR<\/span>\r\n  <span style=\"color: #0000ff;\">auto<\/span> nullp= nullptr;          <span style=\"color: #008000;\">\/\/ type std::nullptr_t<\/span>\r\n  \r\n  <span style=\"color: #2b91af;\">bool<\/span> b = nullptr;           \r\n  std::cout &lt;&lt; std::boolalpha &lt;&lt; <span style=\"color: #a31515;\">\"b: \"<\/span>  &lt;&lt; b &lt;&lt; std::endl;\r\n  <span style=\"color: #0000ff;\">auto<\/span> val= 5;\r\n  <span style=\"color: #0000ff;\">if<\/span> ( nullptr &lt; &amp;val ){ std::cout &lt;&lt; <span style=\"color: #a31515;\">\"nullptr &lt; &amp;val\"<\/span> &lt;&lt; std::endl; }  \r\n\r\n  <span style=\"color: #008000;\">\/\/ calls char*<\/span>\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"overloadTest(nullptr)= \"<\/span> &lt;&lt;  overloadTest(nullptr)&lt;&lt; std::endl;\r\n\r\n  std::cout &lt;&lt; std::endl;\r\n\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;&nbsp;<\/p>\n<p>The <span style=\"font-family: courier new,courier;\">nullptr<\/span> can be used to initialize a pointer of type <span style=\"font-family: courier new,courier;\">long int<\/span> (line 18). But it can not be used to initialize a variable of type<span style=\"font-family: courier new,courier;\"> long int<\/span> (line 18). The automatic type deduction in line 20 is quite interesting. <span style=\"font-family: courier new,courier;\">nullptr<\/span> becomes a value of type <span style=\"font-family: courier new,courier;\">std::nullptr_t.<\/span> The null pointer constant behaves like a boolean value initialized with <span style=\"font-family: courier new,courier;\">false.<\/span> You can observe that in lines 22 &#8211; 25. If the <span style=\"font-family: courier new,courier;\">nullptr<\/span> has to decide between a <span style=\"font-family: courier new,courier;\">long int<\/span> and a pointer, it will decide on a pointer (line 28).<\/p>\n<p>Here is the output of the program.<\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5017\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/nullptr.png\" alt=\"nullptr\" width=\"624\" height=\"216\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/nullptr.png 624w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/nullptr-300x104.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/>&nbsp;<\/p>\n<p>The simple rule is: <strong>Use <span style=\"font-family: courier new,courier;\">nullptr<\/span> instead of<span style=\"font-family: courier new,courier;\"> 0<\/span> or <span style=\"font-family: courier new,courier;\">NULL<\/span>.<\/strong> Still not convinced? Here is my last and strongest point.<\/p>\n<h2>Generic code<\/h2>\n<p>The literal <span style=\"font-family: courier new,courier;\">0<\/span> and <span style=\"font-family: courier new,courier;\">NULL<\/span> show in generic code their true nature. Thanks to template argument deduction both literals are integral types in the function template. There is no hint that both literals were null pointer constants.<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ generic.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;cstddef&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n \r\n<span style=\"color: #0000ff;\">template<\/span>&lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">P<\/span> &gt;\r\n<span style=\"color: #2b91af;\">void<\/span> functionTemplate(P p){\r\n  <span style=\"color: #2b91af;\">int<\/span>* a= p;\r\n}\r\n \r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n  <span style=\"color: #2b91af;\">int<\/span>* a= 0;           \r\n  <span style=\"color: #2b91af;\">int<\/span>* b= NULL;              \r\n  <span style=\"color: #2b91af;\">int<\/span>* c= nullptr;\r\n \r\n  functionTemplate(0);   \r\n  functionTemplate(NULL);\r\n  functionTemplate(nullptr);  \r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>You can use <span style=\"font-family: courier new,courier;\">0<\/span> and <span style=\"font-family: courier new,courier;\">NULL<\/span> to initialize the int pointer in lines 12 and 13. But if you use the values <span style=\"font-family: courier new,courier;\">0<\/span> and <span style=\"font-family: courier new,courier;\">NULL<\/span> as function template arguments, the compiler will loudly complain. The compiler deduces <span style=\"font-family: courier new,courier;\">0<\/span> in the function template to type <span style=\"font-family: courier new,courier;\">int and<\/span> <span style=\"font-family: courier new,courier;\">NULL<\/span> to the type <span style=\"font-family: courier new,courier;\">long int<\/span>. But these observations will not hold for the <span style=\"font-family: courier new,courier;\">nullptr. nullptr<\/span> is in line 12 of type <span style=\"font-family: courier new,courier;\">std::nullptr_t<\/span> and <span style=\"font-family: courier new,courier;\">nullptr<\/span> is in line 8 of type <span style=\"font-family: courier new,courier;\">std::nullptr_t.<\/span><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5018\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/generic.png\" alt=\"generic\" width=\"764\" height=\"261\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/generic.png 764w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/generic-300x102.png 300w\" sizes=\"auto, (max-width: 764px) 100vw, 764px\" \/><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>In my last post, I presented many features in C++ to make your code safer. Which one? Have a look at<a href=\"https:\/\/www.modernescpp.com\/index.php?option=com_content&amp;view=article&amp;id=170;modern-c&amp;catid=35;c&amp;Itemid=271#HighSafetyRequirements\"> high safety requirements <\/a>on the overview page. The key idea of all these features is to use the compiler&#8217;s smartness. Therefore, we follow one of the critical principles of C++:<strong> Compile time errors are better than run time errors.<\/strong><\/p>\n<p>With the next posts, I switch the focus. My focus will change from the C++ features that are important for safety-critical features to the features that are important for performance reasons. I will have in the <a href=\"https:\/\/www.modernescpp.com\/index.php\/inline\">next post<\/a><span id=\"transmark\"> <\/span>a deeper look into <span style=\"font-family: courier new,courier;\">inline.<\/span> Thanks to the keyword <span style=\"font-family: courier new,courier;\">inline,<\/span> the compiler can replace the function call with its function invocation. Therefore, the expensive call of the function becomes superfluous.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The new null pointer nullptr cleans up in C++ with the ambiguity of 0 and the macro NULL.<\/p>\n","protected":false},"author":21,"featured_media":5014,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[364],"tags":[514,496],"class_list":["post-5019","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-embedded","tag-nullptr","tag-pointers"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5019","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=5019"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5019\/revisions"}],"predecessor-version":[{"id":6929,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5019\/revisions\/6929"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5014"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5019"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5019"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5019"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}