{"id":11458,"date":"2026-10-18T13:58:39","date_gmt":"2026-10-18T13:58:39","guid":{"rendered":"https:\/\/www.modernescpp.com\/?p=11458"},"modified":"2026-10-18T13:58:39","modified_gmt":"2026-10-18T13:58:39","slug":"cpp-and-memory-safety-part-1","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/cpp-and-memory-safety-part-1\/","title":{"rendered":"The Problem with C++ Safety (Part 1): Why \u201cIt Works\u201d Isn\u2019t Good Enough"},"content":{"rendered":"\r\n<h2 class=\"wp-block-heading\">In Memory of Rainer Grimm<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Welcome back to the blog of Rainer Grimm! This is the first of hopefully many new C++-related articles in Rainer\u2019s blog. Since you are reading this, you have potentially read many of his articles and have gotten an idea of his passion and his devotion to the C++ community. In this blog, for more than a decade, Rainer has provided the C++ community with countless articles about the latest and greatest of C++.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">With deep sadness you may have already heard the news: Rainer passed away on October 6th 2025, as a victim of his ALS disease. He leaves a big hole in our hearts, but also in the C++ community. He will be sorely missed by many friends, colleagues, and students.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">It would be a shame to let his amazing contribution to the C++ community go to waste. In order to honor his devotion to the community, a few C++ experts, in particular Mateusz Pusz, Jens Weller, Slobodan Dmitrovi\u0107, Ivan \u010cuki\u0107, and me, have come together to continue his journey: bringing the latest and greatest news to you, the readers of Rainer\u2019s blog. I\u2019m making a start here, trying to uphold the spirit of his blog.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Of course there will be little changes: the five of us have our own style, our own interests, our own message. Thus the upcoming sequence of articles will inevitably be a little different from Rainer\u2019s original articles. It will be a mixture of different areas of expertise, of different highlights and of different topics. But one thing will remain: we\u2019ll make sure Rainer\u2019s devotion to quality and insight will be upheld. We\u2019ll make sure to continue on his path to bring valuable information to the C++ community.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">The Problem<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">So let\u2019s start to talk about C++: we have a problem. C++ isn\u2019t memory safe! \u2026<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I suspect that this isn\u2019t particularly new to you. In fact, the NSA published an article back in 2022, in which it explicitly recommended not to use C or C++ for safety and security related software anymore [<a href=\"https:\/\/www.nsa.gov\/Press-Room\/News-Highlights\/Article\/Article\/3215760\/\">1<\/a>]. The wording has softened since the first publication, but the spirit remains the same: prefer memory safe languages.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">But it is not just the US authorities. The recommendation in the \u201cCyber Resilience Act\u201d of the European Union is similar: avoid memory unsafe languages. Although they did not explicitly mention C and C++ as the culprits, the message was clear enough.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This sounds dire, but of course there is a fundamental and very good reasoning behind these articles. According to [<a href=\"https:\/\/digital-strategy.ec.europa.eu\/en\/library\/cyber-resilience-act\">2<\/a>], <em>\u201cHardware and software products are increasingly subject to successful cyberattacks, leading to an estimated global annual cost of cybercrime of 5.5 trillion Euros by 2021.\u201d<\/em><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">5.5 trillion Euros!!! Yes, several trillion Euros have been lost due to malicious attacks, many of them from foreign countries interested in the downfall of our economy and society. And this number alone should be a perfect explanation for the desire to harden our software against cyber attacks.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">But how does this relate to C++? Well, unfortunately some statistics have been pulled out of proportion and bent to emphasize what a significant and devastating impact the lack of memory safety of C++ has on cyber security. Officials therefore advise the use of languages that are considered memory safe.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Now we could start talking about these statistics and we could go into detail why C++ and memory safety in general are not the most important factors for cyber security and why C++ itself is by far not as unreliable and endangering as it sounds [<a href=\"https:\/\/herbsutter.com\/2025\/12\/30\/software-taketh-away-faster-than-hardware-giveth-why-c-programmers-keep-growing-fast-despite-competition-safety-and-ai\/\">3<\/a>]. We could also, as so many people on social media do, start to argue that the arguments against C++ are exaggerated, misinformed or just plain wrong. However, let\u2019s be serious: of course there is truth behind the statements. Truth that cannot really be denied, unfortunately. Therefore, from my perspective, it makes more sense to explore where and why these arguments emerge and what we can do about it.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">An Example<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Based on my many years as a C++ trainer and consultant, I believe I have a pretty good idea about the real problem in our community. In order to make a point, let\u2019s take a look at an example I saw on LinkedIn some time ago [<a href=\"https:\/\/www.linkedin.com\/feed\/update\/urn:li:activity:7409153900911468544\/\">4<\/a>]. A developer posted code for a \u201cPalindrome Check in C++\u201d. Here is the original code:<\/p>\r\n\r\n\r\n<!-- HTML generated using hilite.me -->\r\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\r\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #099;\">#include<\/span> <span style=\"color: #09f; font-style: italic;\">&lt;iostream&gt;<\/span>\r\n<span style=\"color: #069; font-weight: bold;\">using<\/span> <span style=\"color: #069; font-weight: bold;\">namespace<\/span> <span style=\"color: #0cf; font-weight: bold;\">std<\/span>;\r\n\r\n<span style=\"color: #078; font-weight: bold;\">int<\/span> <span style=\"color: #c0f;\">main<\/span>(){\r\n    string str <span style=\"color: #555;\">=<\/span> <span style=\"color: #c30;\">\"nitin\"<\/span>;\r\n    <span style=\"color: #078; font-weight: bold;\">int<\/span> size <span style=\"color: #555;\">=<\/span> str.size();\r\n    <span style=\"color: #078; font-weight: bold;\">int<\/span> firstPointer <span style=\"color: #555;\">=<\/span> <span style=\"color: #f60;\">0<\/span>, lastPointer <span style=\"color: #555;\">=<\/span> size<span style=\"color: #f60;\">-1<\/span>;\r\n\r\n    <span style=\"color: #069; font-weight: bold;\">while<\/span>(firstPointer<span style=\"color: #555;\">&lt;=<\/span>lastPointer){\r\n        <span style=\"color: #069; font-weight: bold;\">if<\/span>(str[firstPointer]<span style=\"color: #555;\">!=<\/span>str[lastPointer]){\r\n            cout<span style=\"color: #555;\">&lt;&lt;<\/span><span style=\"color: #c30;\">\"not palindrome\"<\/span>;\r\n            <span style=\"color: #069; font-weight: bold;\">return<\/span> <span style=\"color: #f60;\">0<\/span>;\r\n        }\r\n        firstPointer<span style=\"color: #555;\">++<\/span>;\r\n        lastPointer<span style=\"color: #555;\">--<\/span>;\r\n    }\r\n\r\n    cout<span style=\"color: #555;\">&lt;&lt;<\/span><span style=\"color: #c30;\">\"palindrome\"<\/span>;\r\n\r\n    <span style=\"color: #069; font-weight: bold;\">return<\/span> <span style=\"color: #f60;\">0<\/span>;\r\n}\r\n<\/pre>\r\n<\/div>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Before reading on, please take a look at this code and tell me if you see any problems \u2014 in particular any safety or security related issues.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">\u2026<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">OK, I assume you\u2019ve taken a good look and have found a couple of issues \u2014 yes, more than one. But in order to stay positive and in order to make an attempt, let\u2019s start with the positive aspect of this code: yes, all semicolons in this code are correctly placed. Well done!<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">But unfortunately that\u2019s it. The list of deficiencies is unfortunately much longer:<\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>a using directive for namespace <code>std<\/code> shouldn\u2019t even be used in example code anymore. Inexperienced developers might get the impression it\u2019s a good idea and apply this in their own code. So just to be explicit: this is a terrible idea. Core Guideline SF.7 will help you to understand the details [<a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#rs-using-directive\">5<\/a>].<\/li>\r\n\r\n\r\n\r\n<li>the <code>main()<\/code> function is used to demonstrate the code instead of immediately providing a properly named function for the task. We could argue that it is just an example, but we could also argue that this is just lazy. Or is it just code written by AI? Perhaps, but more on that later.<\/li>\r\n\r\n\r\n\r\n<li>the \u201cinput\u201d string and the subsequent <code>size<\/code> variable are not <code>const<\/code> qualified. Which is a pity, because they are never changed, but only read. This clearly violates Core Guideline Con.1 [<a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#rconst-immutable\">6<\/a>].<\/li>\r\n\r\n\r\n\r\n<li>the variables <code>firstPointer<\/code> and <code>lastPointer<\/code> are defined within the same statement. While this works and compiles of course, it is considered bad practice today. Please, don\u2019t do this anymore! See also Core Guideline ES.10 [<a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#es10-declare-one-name-only-per-declaration\">7<\/a>].<\/li>\r\n\r\n\r\n\r\n<li>although the variables are called <code>Pointer<\/code>, they are actually of type <code>int<\/code>. Thus the name is misleading at best \u2014 or just plain wrong.<\/li>\r\n\r\n\r\n\r\n<li><code>lastPointer<\/code> is set to <code>size-1<\/code>, which only \u201cworks\u201d because the chosen type is <code>int<\/code>, not <code>size_t<\/code>. Yes, I agree, in this case everything is fine, but a generalized function would have to deal with the special case, which is just ignored here.<\/li>\r\n\r\n\r\n\r\n<li>the characters of the string are accessed via the subscript operator. This operation takes a <code>size_t<\/code>, not an <code>int<\/code>, and does not perform any bounds checking, which could quickly lead to undefined behavior.<\/li>\r\n\r\n\r\n\r\n<li><code>firstPointer<\/code> and <code>lastPointer<\/code> are postfix incremented, although the old value is neither needed nor used in the code. This potential waste of resources is warned against in Core Guideline P.9 [<a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#rp-waste\">8<\/a>].<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">A Generalized Function<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This (hopefully) feels like a crushing review. But you might want to argue: <em>\u201cOK, Klaus, that may be a little picky. I get it, a lot of core guidelines were violated, but it\u2019s just a simple example. After all, it works, right?\u201d<\/em><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Well, I honestly don\u2019t think that it is a good idea to post \u201csimple\u201d code examples that violate so many of the community\u2019s best practices. Actually, in my opinion it is a terrible idea. However, we could be well-meaning at this point and imagine a second attempt to solve the problem, this time with a generalized function named <code>is_palindrome()<\/code>:<\/p>\r\n\r\n\r\n<!-- HTML generated using hilite.me -->\r\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\r\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #078; font-weight: bold;\">bool<\/span> <span style=\"color: #c0f;\">is_palindrome<\/span>( std<span style=\"color: #555;\">::<\/span>string_view str )\r\n{\r\n    <span style=\"color: #069; font-weight: bold;\">if<\/span>( str.empty() )\r\n        <span style=\"color: #069; font-weight: bold;\">return<\/span> <span style=\"color: #366;\">true<\/span>;\r\n\r\n    <span style=\"color: #069; font-weight: bold;\">auto<\/span> begin{ str.begin() };\r\n    <span style=\"color: #069; font-weight: bold;\">auto<\/span> end  { str.end() };\r\n    <span style=\"color: #555;\">--<\/span>end;  <span style=\"color: #09f; font-style: italic;\">\/\/ We know the string is not empty, so we can decrement<\/span>\r\n\r\n    <span style=\"color: #069; font-weight: bold;\">while<\/span>( begin<span style=\"color: #555;\">&lt;=<\/span>end ) {\r\n        <span style=\"color: #069; font-weight: bold;\">if<\/span>( <span style=\"color: #555;\">*<\/span>begin <span style=\"color: #555;\">!=<\/span> <span style=\"color: #555;\">*<\/span>end ) {\r\n            <span style=\"color: #069; font-weight: bold;\">return<\/span> <span style=\"color: #366;\">false<\/span>;\r\n        }\r\n        <span style=\"color: #555;\">++<\/span>begin;\r\n        <span style=\"color: #555;\">--<\/span>end;\r\n    }\r\n\r\n    <span style=\"color: #069; font-weight: bold;\">return<\/span> <span style=\"color: #366;\">true<\/span>;\r\n}\r\n\r\n<span style=\"color: #078; font-weight: bold;\">int<\/span> <span style=\"color: #c0f;\">main<\/span>()\r\n{\r\n    std<span style=\"color: #555;\">::<\/span>string <span style=\"color: #069; font-weight: bold;\">const<\/span> str{ <span style=\"color: #c30;\">\"nitin\"<\/span> };\r\n\r\n    <span style=\"color: #069; font-weight: bold;\">if<\/span>( is_palindrome(str) )\r\n        std<span style=\"color: #555;\">::<\/span>cout <span style=\"color: #555;\">&lt;&lt;<\/span> <span style=\"color: #c30;\">\"palindrome<\/span><span style=\"color: #c30; font-weight: bold;\">\\n<\/span><span style=\"color: #c30;\">\"<\/span>;\r\n    <span style=\"color: #069; font-weight: bold;\">else<\/span>\r\n        std<span style=\"color: #555;\">::<\/span>cout <span style=\"color: #555;\">&lt;&lt;<\/span> <span style=\"color: #c30;\">\"not palindrome<\/span><span style=\"color: #c30; font-weight: bold;\">\\n<\/span><span style=\"color: #c30;\">\"<\/span>;\r\n\r\n    <span style=\"color: #069; font-weight: bold;\">return<\/span> <span style=\"color: #f60;\">0<\/span>;\r\n}\r\n<\/pre>\r\n<\/div>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">OK, OK, I admit it, I\u2019m providing this example to make a point. For this reason I also don\u2019t adhere to all the best practices. But we, again well-meaning, could argue that this is a much better attempt to solve the problem. So please, take a close look at the <code>is_palindrome()<\/code> function and tell me if you are certain that there are no safety or security related issues.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">\u2026<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I hope you\u2019ve really taken a good look. You might come up with the following summary: <em>\u201cOK, Klaus, assuming you want to keep this simple and therefore really only want to apply this to a <code>std::string<\/code>, and considering this is only the next iteration, this appears to work well.\u201d<\/em><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">But wait: the question wasn\u2019t \u201cdoes it work well\u201d, but \u201care you certain\u201d! So are you certain, i.e. 100% certain, that this code does not contain any safety or security related issues?<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">At this point you might pause and reconsider. Honestly, if I were you, I wouldn\u2019t be certain either. Although the code is just a few lines long, it is already difficult to think it through in every detail. Are all special cases covered? Could this result in an infinite loop? Could this accidentally access any invalid memory location? Are there other sources of undefined behavior? I can\u2019t be certain by just looking at it. I\u2019d need more time, potentially much more time to really think it through.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">For this reason \u2014 the reason of not being certain \u2014 I would rate this as poor code. Yes, seriously, poor code.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><em>\u201cBut Klaus, isn\u2019t this a little too harsh? This code isn\u2019t so bad after all!\u201d<\/em><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">No, I\u2019m dead serious. I would even argue that this is not the kind of C++ code we write and should write today, i.e. \u201cmodern C++\u201d code. This is \u201cclassic C++\u201d to me. And I\u2019m very confident in saying this, because the modern solution is so much shorter and so much simpler.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">What\u2019s next?<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">In the second part we\u2019ll take a look at the modern C++ solution and discuss why it is superior to the classic solution. So stay tuned :-)<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">References<\/h2>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>[1] <a href=\"https:\/\/www.nsa.gov\/Press-Room\/News-Highlights\/Article\/Article\/3215760\/\">https:\/\/www.nsa.gov\/Press-Room\/News-Highlights\/Article\/Article\/3215760\/<\/a><\/li>\r\n\r\n\r\n\r\n<li>[2] <a href=\"https:\/\/digital-strategy.ec.europa.eu\/en\/library\/cyber-resilience-act\">https:\/\/digital-strategy.ec.europa.eu\/en\/library\/cyber-resilience-act<\/a><\/li>\r\n\r\n\r\n\r\n<li>[3] <a href=\"https:\/\/herbsutter.com\/2025\/12\/30\/software-taketh-away-faster-than-hardware-giveth-why-c-programmers-keep-growing-fast-despite-competition-safety-and-ai\/\">https:\/\/herbsutter.com\/2025\/12\/30\/software-taketh-away-faster-than-hardware-giveth-why-c-programmers-keep-growing-fast-despite-competition-safety-and-ai\/<\/a><\/li>\r\n\r\n\r\n\r\n<li>[4] <a href=\"https:\/\/www.linkedin.com\/feed\/update\/urn:li:activity:7409153900911468544\/\">https:\/\/www.linkedin.com\/feed\/update\/urn:li:activity:7409153900911468544\/<\/a><\/li>\r\n\r\n\r\n\r\n<li>[5] <a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#rs-using-directive\">http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#rs-using-directive<\/a><\/li>\r\n\r\n\r\n\r\n<li>[6] <a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#rconst-immutable\">http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#rconst-immutable<\/a><\/li>\r\n\r\n\r\n\r\n<li>[7] <a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#es10-declare-one-name-only-per-declaration\">http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#es10-declare-one-name-only-per-declaration<\/a><\/li>\r\n\r\n\r\n\r\n<li>[8] <a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#rp-waste\">http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#rp-waste<\/a><\/li>\r\n<\/ul>\r\n","protected":false},"excerpt":{"rendered":"<p>Rainer Grimm\u2019s blog continues. In this first article of a new series, Klaus Iglberger looks at why C++ is called memory unsafe and argues that the real problem isn\u2019t the language itself, but how we write and teach it.<\/p>\n","protected":false},"author":30,"featured_media":11465,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[567],"tags":[466],"class_list":["post-11458","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-safety","tag-safety"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/11458","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\/30"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=11458"}],"version-history":[{"count":5,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/11458\/revisions"}],"predecessor-version":[{"id":11467,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/11458\/revisions\/11467"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/11465"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=11458"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=11458"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=11458"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}