{"id":5483,"date":"2018-08-10T15:56:36","date_gmt":"2018-08-10T15:56:36","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-when-you-can-t-throw-an-exception\/"},"modified":"2024-12-05T11:24:35","modified_gmt":"2024-12-05T11:24:35","slug":"c-core-guidelines-when-you-can-t-throw-an-exception","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-when-you-can-t-throw-an-exception\/","title":{"rendered":"C++ Core Guidelines: finally in C++"},"content":{"rendered":"<p>To make my point clear, this post is about the exceptional case that you can not throw an exception. If your program runs in a restricted embedded environment or you have to fulfil a hard-real-time requirement, this situation may be not so exceptional to you.<\/p>\n<p><!--more--><\/p>\n<div id=\"attachment_5482\" style=\"width: 1290px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-5482\" class=\"wp-image-5482 size-full\" style=\"display: block; margin-left: auto; margin-right: auto;\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/08\/accident-994009_1280.jpg\" alt=\"accident 994009 1280\" width=\"1280\" height=\"960\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/08\/accident-994009_1280.jpg 1280w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/08\/accident-994009_1280-300x225.jpg 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/08\/accident-994009_1280-1024x768.jpg 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/08\/accident-994009_1280-768x576.jpg 768w\" sizes=\"auto, (max-width: 1280px) 100vw, 1280px\" \/><p id=\"caption-attachment-5482\" class=\"wp-caption-text\">Bild von <a href=\"https:\/\/pixabay.com\/de\/users\/succo-96729\/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=994007\">succo<\/a> auf <a href=\"https:\/\/pixabay.com\/de\/\/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=994007\">Pixabay<\/a><\/p><\/div>\n<p>Let&#8217;s start with the exceptional environment in which you can&#8217;t throw exceptions. My original plan was to write at least about the rules E.19 to E.27. But I get stuck at rule E.19.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"E19_Use_a_final_action_object_to_express_cleanup_if_no_suitable_resource_handle_is_available\"><\/span><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Re-finally\">E.19: Use a <code class=\"highlighter-rouge no-highlight\">final_action<\/code> object to express cleanup if no suitable resource handle is available<\/a><span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p class=\"pv-top-card-section__name Sans-26px-black-85%\">The first rule may surprise you because you have never heard about <span style=\"font-family: courier new, courier;\">final_action<\/span>. Me too. Therefore I researched. During my research, I found an excellent post on this rule by <strong>Bart\u0142omiej Filipek<\/strong>.\u00a0Bart\u0142omiej Filipek is the author of the well-known C++-blog: <a href=\"https:\/\/www.bfilipek.com\/p\/start-here.html\">Bartek&#8217;s coding blog<\/a>. With his permission, I&#8217;m happy to incorporate his post <a href=\"https:\/\/www.bfilipek.com\/2017\/04\/finalact.html\">Beautiful code: final_act from GSL<\/a> into my post. Here we are.<\/p>\n<p>Sometimes there\u2019s a need to invoke a particular action at the end of the scope: it could be a resource releasing code, flag set, code guard, begin\/end function calls, etc. Recently, I\u2019ve found a beautiful utility that helps in that cases.<br \/>\nLet\u2019s meet <span style=\"font-family: courier new, courier;\"><code>gsl::final_act<\/code>\/<code>finally<\/code>.<\/span><\/p>\n<h3><span class=\"ez-toc-section\" id=\"Intro\"><\/span>Intro<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><strong>Follow-up<\/strong> post here: <a href=\"http:\/\/www.bfilipek.com\/2017\/04\/finalact-follow-up.html\" target=\"_self\" rel=\"noopener\">link<\/a>.<\/p>\n<p>Imagine we have the following code:<\/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: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">addExtraNodes<\/span>();\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">removeExtraNodes<\/span>();\n\n<span style=\"color: #007788; font-weight: bold;\">bool<\/span> Scanner<span style=\"color: #555555;\">::<\/span>scanNodes()\n{\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ code...<\/span>\n    addExtraNodes();\n\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ code...<\/span>\n    removeExtraNodes();\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #336666;\">true<\/span>;\n}\n<\/pre>\n<\/div>\n<p>We have a bunch of objects that <strong><span style=\"font-family: courier new, courier;\"><code>scanNodes<\/code><\/span><\/strong> scans (global or shared container), but we need to add some extra nodes to check. We want to preserve the initial container state, so in the end, we must remove those additional nodes.<\/p>\n<p>Of course, the design of the whole scan code could be much better so that we work on a copy of the container, and adding or removing extra stuff would not be a problem. But there are places, especially in legacy code, where you work on some global container, and special care needs to be taken when changing it. Many bugs can happen when you modify a state and someone expects a different state of the shared container.<\/p>\n<p>My code seems to be working as expected\u2026 right? I call <strong><span style=\"font-family: courier new, courier;\"><code>removeExtraNodes<\/code><\/span><\/strong> at the end of the function.<\/p>\n<p>But what if there are multiple returns from <strong><span style=\"font-family: courier new, courier;\"><code>scanNodes<\/code><\/span><\/strong>? It\u2019s simple: we need to add multiple calls to <strong><span style=\"font-family: courier new, courier;\"><code>removeExtraNodes<\/code>.<\/span><\/strong> Ok\u2026.<\/p>\n<p>What if there are some exceptions thrown? Then we also need to call our cleanup function before we throw\u2026<\/p>\n<p>So it appears we need to call <strong><span style=\"font-family: courier new, courier;\"><code>removeExtraNodes<\/code><\/span><\/strong> not only before the last return!<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Help_needed\"><\/span>Help needed<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Let\u2019s look at the C++ Core Guidelines. They suggest doing the following thing:<\/p>\n<p><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#e19-use-a-final_action-object-to-express-cleanup-if-no-suitable-resource-handle-is-available\">E.19: Use a final_action object to express cleanup if no suitable resource handle is available<\/a><\/p>\n<p>The guideline says that we should strive for a better design, but still, it\u2019s better than goto; exit approach or doing nothing.<\/p>\n<p>Ok\u2026 but what\u2019s the solution here:<\/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: #007788; font-weight: bold;\">bool<\/span> Scanner<span style=\"color: #555555;\">::<\/span>scanNodes()\n{\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ code...<\/span>\n    addExtraNodes();\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> _ <span style=\"color: #555555;\">=<\/span> finally([] { removeExtraNodes(); });\n\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ code...<\/span>\n\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #336666;\">true<\/span>;\n}\n<\/pre>\n<\/div>\n<p>What happened here?<\/p>\n<p>All I did was wrap the call to <span style=\"font-family: courier new, courier;\"><strong><code>removeExtraNodes<\/code><\/strong><\/span>\u00a0a particular object that will call a given callable object in its destructor. This is precisely what we need!<\/p>\n<p>Where can we find that magical <span style=\"font-family: courier new, courier;\"><code>finally()<\/code><\/span> code?<\/p>\n<p>Just see <a href=\"https:\/\/github.com\/Microsoft\/GSL\/blob\/master\/include\/gsl\/gsl_util\">Guideline Support Library\/gsl_util.h<\/a>.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Under_the_hood\"><\/span>Under the hood<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The code is short, so I can even paste it here:<\/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;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">F<\/span><span style=\"color: #555555;\">&gt;<\/span>\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">final_act<\/span>\n{\n<span style=\"color: #9999ff;\">public:<\/span>\n    <span style=\"color: #006699; font-weight: bold;\">explicit<\/span> final_act(F f) noexcept \n      <span style=\"color: #555555;\">:<\/span> f_(std<span style=\"color: #555555;\">::<\/span>move(f)), invoke_(<span style=\"color: #336666;\">true<\/span>) {}\n\n    final_act(final_act<span style=\"color: #555555;\">&amp;&amp;<\/span> other) noexcept \n     <span style=\"color: #555555;\">:<\/span> f_(std<span style=\"color: #555555;\">::<\/span>move(other.f_)), \n       invoke_(other.invoke_)\n    {\n        other.invoke_ <span style=\"color: #555555;\">=<\/span> <span style=\"color: #336666;\">false<\/span>;\n    }\n\n    final_act(<span style=\"color: #006699; font-weight: bold;\">const<\/span> final_act<span style=\"color: #555555;\">&amp;<\/span>) <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">delete<\/span>;\n    final_act<span style=\"color: #555555;\">&amp;<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">=<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> final_act<span style=\"color: #555555;\">&amp;<\/span>) <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">delete<\/span>;\n\n    <span style=\"color: #555555;\">~<\/span>final_act() noexcept\n    {\n        <span style=\"color: #006699; font-weight: bold;\">if<\/span> (invoke_) f_();\n    }\n\n<span style=\"color: #9999ff;\">private:<\/span>\n    F f_;\n    <span style=\"color: #007788; font-weight: bold;\">bool<\/span> invoke_;\n};\n<\/pre>\n<\/div>\n<p>Isn\u2019t that beautiful?!<\/p>\n<p>The above class takes a callable object &#8211; <strong><span style=\"font-family: courier new, courier;\"><code>f_<\/code><\/span><\/strong> It will call it when it\u2019s about to be destroyed. So even if your code returns early or throws an exception, your cleanup code must be invoked.<\/p>\n<p>To work nicely with move semantics, there has to be an additional boolean parameter <strong><span style=\"font-family: courier new, courier;\"><code>invoke_<\/code><\/span><\/strong>. This will guarantee that we won\u2019t call the code for temporary objects. See this commit for more information if needed: <a href=\"https:\/\/github.com\/Microsoft\/GSL\/pull\/90\"><br \/>\nFinal_act copy\/move semantics is wrong<\/a>.<\/p>\n<p><span lang=\"EN-GB\" style=\"font-family: 'Arial', sans-serif; color: black;\">In C++17, we have <\/span><span style=\"font-size: 12pt; font-family: 'Times New Roman', serif;\"><a href=\"http:\/\/www.bfilipek.com\/2017\/01\/cpp17features.html#template-argument-deduction-for-class-templates\"><span lang=\"EN-GB\" style=\"font-size: 11pt; font-family: 'Arial', sans-serif; color: #1155cc;\">Template argument deduction for class templates<\/span><\/a><\/span><span style=\"font-family: 'Arial', sans-serif; color: black;\"> <span lang=\"EN-GB\">\u2013 that\u2019s why you can also declare <span style=\"font-family: courier new, courier;\">final_act<\/span> object as: <\/span><\/span><\/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%;\">final_act <span style=\"color: #cc00ff;\">_f<\/span>([] { removeExtraNodes(); })<\/pre>\n<\/div>\n<p>Before C++17, we had to use the helper function <span style=\"font-family: courier new, courier;\">finally<\/span> to make our life easier:<\/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;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">F<\/span><span style=\"color: #555555;\">&gt;<\/span>\n<span style=\"color: #006699; font-weight: bold;\">inline<\/span> final_act<span style=\"color: #555555;\">&lt;<\/span>F<span style=\"color: #555555;\">&gt;<\/span> finally(<span style=\"color: #006699; font-weight: bold;\">const<\/span> F<span style=\"color: #555555;\">&amp;<\/span> f) noexcept\n{\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> final_act<span style=\"color: #555555;\">&lt;<\/span>F<span style=\"color: #555555;\">&gt;<\/span>(f);\n}\n\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">F<\/span><span style=\"color: #555555;\">&gt;<\/span>\n<span style=\"color: #006699; font-weight: bold;\">inline<\/span> final_act<span style=\"color: #555555;\">&lt;<\/span>F<span style=\"color: #555555;\">&gt;<\/span> finally(F<span style=\"color: #555555;\">&amp;&amp;<\/span> f) noexcept\n{\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> final_act<span style=\"color: #555555;\">&lt;<\/span>F<span style=\"color: #555555;\">&gt;<\/span>(std<span style=\"color: #555555;\">::<\/span>forward<span style=\"color: #555555;\">&lt;<\/span>F<span style=\"color: #555555;\">&gt;<\/span>(f));\n}\n<\/pre>\n<\/div>\n<p>So, all in all, we can use <code>finally()<\/code>\u00a0the function in the client code. Maybe that could change in C++17 as we\u2019ll get <a href=\"http:\/\/www.bfilipek.com\/2017\/01\/cpp17features.html#template-argument-deduction-for-class-templates\">Template argument deduction for class templates<\/a>.<\/p>\n<p>What\u2019s nice about this code?<\/p>\n<ul>\n<li>Clean, simple code<\/li>\n<li>Expressive; no comments needed<\/li>\n<li>Does one thing only<\/li>\n<li>It\u2019s generic, so it works on anything that\u2019s callable<\/li>\n<li>Modern C++: so supports move semantics, noexcept,<\/li>\n<\/ul>\n<h3><span class=\"ez-toc-section\" id=\"Important_note_final_act_should_be_noexcept\"><\/span>Important note: final act should be noexcept<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>As explained many times through the comments in GSL repo (for example,<a href=\"https:\/\/github.com\/Microsoft\/GSL\/pull\/13\"> here<\/a>),<a href=\"https:\/\/github.com\/Microsoft\/GSL\/issues?utf8=%E2%9C%93&amp;q=is%3Aissue%20is%3Aclosed%20final_act\"> other issues <\/a>and from<a href=\"https:\/\/github.com\/Microsoft\/GSL\/issues\/12#issuecomment-143589911\"> Final_act can lead to program termination if the final act throws an exception<\/a>:<\/p>\n<p>Final_act should be <span style=\"font-family: courier new, courier;\">noexcept.<\/span> It is conceptually just a handy way for the user to conjure up a destructor, and destructors should be noexcept. If something it invokes happens to throw, then the program will terminate.<\/p>\n<p>In other words, you should write the code that will be called with the same assumptions as other destructor code\u2026 so don\u2019t throw anything there. That might be a little limitation when you want to call some \u2018normal\u2019 code, not just some clean-up stuff (on the other hand, might that would be a bad design after all?).<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Where_could_be_used\"><\/span>Where could be used?<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Just to be clear: don\u2019t use <strong><span style=\"font-family: courier new, courier;\"><code>finally<\/code><\/span><\/strong> approach too often! With the proper design, your objects shouldn\u2019t work in a global state and take benefit from RAII as much as possible. Still, there are situations where <strong><span style=\"font-family: courier new, courier;\"><code>finally<\/code><\/span><\/strong> it is pleasant to use:<\/p>\n<ul>\n<li><span lang=\"EN-GB\" style=\"font-family: 'Arial', sans-serif;\">transactions<\/span><span lang=\"EN-GB\" style=\"font-family: 'Arial', sans-serif;\">. That\u2019s a general term for all actions that should be reverted when something fails. If you copied 95% of a file and got an error, you cannot leave such possibly corrupted files; you have to remove them and maybe start again. If you are connected to a database and want to write some records, you assume it\u2019s <b>atomic<\/b>. <\/span><\/li>\n<li>begin\/end functions &#8211; where you\u2019re required to call <strong><span style=\"font-family: courier new, courier;\"><code>end<\/code><\/span><\/strong> after something starts. As in our example.<\/li>\n<li>flag setters. You have a shared flag and set it to a new state, but you have to reset it to the old state when you\u2019re done.<\/li>\n<li>resources without RAII support. The guideline shows an example with malloc\/free. It might work if you cannot wrap it in an RAII object (for example, by using smart pointers and custom deleters).<\/li>\n<li>safely closing the connection &#8211; as another example of resource clean-up.<\/li>\n<\/ul>\n<p>Do you see other places where <strong><span style=\"font-family: courier new, courier;\"><code>final_act<\/code><\/span><\/strong> can help?<\/p>\n<p>You can also look at this list: <a href=\"https:\/\/rnestler.github.io\/c-list-of-scopeguard.html\">C++ List of ScopeGuard<\/a> that appeared sometime on Reddit (<a href=\"https:\/\/www.reddit.com\/r\/cpp\/comments\/4ecf5a\/c_list_of_scopeguard\/\">thread here<\/a>)<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Summary\"><\/span>Summary<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><strong>Follow-up<\/strong> post here: <a href=\"http:\/\/www.bfilipek.com\/2017\/04\/finalact-follow-up.html\" target=\"_self\" rel=\"noopener\">link<\/a>.<\/p>\n<p><strong><span style=\"font-family: courier new, courier;\"><code>final_act<\/code>\/<code>finally<\/code><\/span><\/strong> is a beautiful and well-designed tool that can help with the dirty job of cleaning stuff. In your code, you should go for a better approach to clean things\/resources, but if that\u2019s not possible <span style=\"font-family: courier new, courier;\"><code>final_act<\/code><\/span> is a great solution.<\/p>\n<p>Do you use similar classes to clean things in your code?<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Whats_next\"><\/span>What&#8217;s next?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>if you can&#8217;t throw an exception and can&#8217;t use it finally, you have a problem. I will solve this issue in my <a href=\"https:\/\/goo.gl\/2ugQXq\">next post<\/a>.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Further_information\"><\/span>Further information<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Recently <strong>Bart\u0142omiej Filipek <\/strong>published his first book, <strong>C++17 in Detail<\/strong>. If you&#8217;d like to learn the new standard effectively and practically, you can check out the book here: <a href=\"https:\/\/leanpub.com\/cpp17indetail\" target=\"_blank\" rel=\"noopener\">https:\/\/leanpub.com\/cpp17indetail<\/a>.<strong>\u00a0<\/strong><\/p>\n<h3><span class=\"ez-toc-section\" id=\"For_Free_Four_Vouchers_for_C_in_Detail\"><\/span>For Free: Four Vouchers for C++ in Detail<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>I&#8217;m happy that <strong>Bart\u0142omiej Filipek <\/strong>gave me four vouchers for his books. Read here the details to get them:<a href=\"https:\/\/www.modernescpp.com\/index.php\/four-vouchers-to-win\"> For Free: Four Vouchers to Win<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>To make my point clear, this post is about the exceptional case that you can not throw an exception. If your program runs in a restricted embedded environment or you have to fulfil a hard-real-time requirement, this situation may be not so exceptional to you.<\/p>\n","protected":false},"author":21,"featured_media":5482,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[478,479,480],"class_list":["post-5483","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c","tag-error-handling","tag-exceptions","tag-finally"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5483","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=5483"}],"version-history":[{"count":2,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5483\/revisions"}],"predecessor-version":[{"id":10439,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5483\/revisions\/10439"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5482"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5483"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5483"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5483"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}