{"id":11471,"date":"2026-11-01T14:59:51","date_gmt":"2026-11-01T14:59:51","guid":{"rendered":"https:\/\/www.modernescpp.com\/?p=11471"},"modified":"2026-11-01T14:59:51","modified_gmt":"2026-11-01T14:59:51","slug":"cpp-and-memory-safety-part-2","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/cpp-and-memory-safety-part-2\/","title":{"rendered":"The Problem with C++ Safety (Part 2): Modern C++ Is a Mindset, Not a Standard"},"content":{"rendered":"\r\n<p class=\"wp-block-paragraph\">In the <a href=\"https:\/\/www.modernescpp.com\/index.php\/cpp-and-memory-safety-part-1\/\">first part<\/a> of this article, we have taken a look at two attempts to decide whether a given string is a palindrome. Both implementations were written in \u201cClassic C++\u201d and didn\u2019t feel great: the code was difficult to read, hard to understand and consequently the defects were difficult to detect. Now it\u2019s time to continue the story and to take a look at a better solution, the \u201cModern C++\u201d solution.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">A Modern C++ Solution<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">So let\u2019s take a look at a modern C++ solution.<\/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%;\">[[nodiscard]] <span style=\"color: #078; font-weight: bold;\">bool<\/span> is_palindrome( std<span style=\"color: #555;\">::<\/span>string_view str )\r\n{\r\n    <span style=\"color: #069; font-weight: bold;\">return<\/span> std<span style=\"color: #555;\">::<\/span>equal( str.cbegin(), str.cbegin()<span style=\"color: #555;\">+<\/span>str.size()<span style=\"color: #555;\">\/<\/span><span style=\"color: #f60;\">2U<\/span>, str.crbegin() );\r\n}\r\n<\/pre>\r\n<\/div>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Yes, it\u2019s that simple: a single function call to the <code>std::equal()<\/code> algorithm. We compare the first half of the range represented by forward iterators with the second half of the range represented by reverse iterators.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><em>\u201cBut Klaus, wait a second: this <code>std::equal()<\/code> algorithm is ages old! This has been part of C++98! This isn\u2019t modern, is it?\u201d<\/em><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">If this is what you are thinking, then I have some important information for you: modern C++ is not about new features or new C++ standards. It is about writing correct, fast and safe code by default. It is about a certain mindset. So to prove my point, ask yourself the question from before: are you 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\">There are none, right? And it is so easy to verify: no <code>if<\/code> statements \u2014 in fact, no conditionals at all, no pointers or indices, no explicit loop. It\u2019s just a single, simple function call. So this code is correct by inspection. It is correct by default. And it is simple. And fast.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">There is even a newer, even more elegant solution:<\/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%;\">[[nodiscard]] <span style=\"color: #078; font-weight: bold;\">bool<\/span> is_palindrome( std<span style=\"color: #555;\">::<\/span>string_view str )\r\n{\r\n    <span style=\"color: #069; font-weight: bold;\">return<\/span> std<span style=\"color: #555;\">::<\/span>ranges<span style=\"color: #555;\">::<\/span>equal( str, str <span style=\"color: #555;\">|<\/span> std<span style=\"color: #555;\">::<\/span>views<span style=\"color: #555;\">::<\/span>reverse );\r\n}\r\n<\/pre>\r\n<\/div>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This is the C++20 ranges-based solution. We are using the <code>std::ranges::equal()<\/code> function on the string and its reverse representation directly. We don\u2019t even need iterators anymore. Admittedly, we are now comparing the entire range and not just the first and second half. However, performance aside, the simplicity, the elegance, and the correctness by default are amazing! This is what we refer to as \u201cModern C++\u201d.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">The Real Problem<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><em>\u201cOK, Klaus, I agree this is simpler and correct by default. But does this really mean that the loop-based solution is bad? After all, it works, doesn\u2019t it?\u201d<\/em><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">You are correct, it \u201cworks\u201d, ignoring the UB for single-character strings. But it is more complicated, requires more effort to verify, takes more time to write, is more difficult to read and understand, requires considerably more testing and just isn\u2019t correct by default. All of which means that, in the end, it is considerably more expensive, too. There simply isn\u2019t a good enough reason to write it in this classic style anymore. This is exactly what I perceive as the real problem in our community.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Too many C++ developers have not embraced modern C++ yet and still use the dangerous and more error-prone constructs by default. Too many C++ developers don\u2019t know about the modern ways of doing things or, for whatever reason, still prefer to write the more explicit code. Because of this, they work by default in the \u201cunsafe mode\u201d of C++.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">To me this feels like an educational problem, a teaching issue. For too many decades people have written this classic C++ and \u201cit was OK\u201d. By now people feel too comfortable, feel too familiar with this style. This is the real problem.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Unfortunately, this problem is currently getting scaled up significantly: With the use of AI tools, people generate this kind of classic C++ automatically. And yes, I have got proof: I asked ChatGPT to generate an <code>is_palindrome()<\/code> function for me (see Figure 1). Guess what: it gave me almost exactly the function from the original LinkedIn post. And no: it didn\u2019t even consider suggesting the use of an algorithm.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image aligncenter size-large\"><img decoding=\"async\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2026\/10\/chatgpt-is-palindrome.png\" alt=\"ChatGPT\u2019s solution for an is_palindrome() function\" \/>\r\n<figcaption class=\"wp-element-caption\">Figure 1: ChatGPT\u2019s solution for an <code>is_palindrome()<\/code> function<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">So why don\u2019t these modern tools use the modern way? Well, despite the name, AI has nothing to do with intelligence. It is a statistics-based tool. If more people use the classic way, then statistically this is the \u201ccorrect\u201d solution. So it is not a big surprise that AI tools will rather write a <code>for<\/code> loop for you instead of using an algorithm.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I should be honest and state that this is not true for every AI tool on the market. Some are better than others, some actually suggest using an algorithm. However, this unfortunately doesn\u2019t resolve the problem: AI tools may suggest outdated solutions, which are not best practice anymore.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Luckily many people in the community know better than the AI tool and know about the modern solutions. Let me use this opportunity for a shout-out to some people that quickly posted a good and modern solution to the original LinkedIn post. Many thanks to Alex Dathskovsky and Sergii Rybin for posting an algorithm-based solution. Honestly, we need more people like you that help to spread the information on how things should be done today. Thank you very much!<\/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\">So what else can we do? I for one can do my part as a C++ trainer: I can tell people. I can teach people. I can show people. And this is what I want to do here in Rainer Grimm\u2019s blog: in the coming months I want to talk about the modern way of doing things in C++. I want to demonstrate how we work today, in the hope that this makes a difference, in the hope of establishing the modern C++ mindset and of maybe (hopefully!) contributing to the general realization, even beyond the C++ community, that C++ can be incredibly safe, if we just use it as it is supposed to be used.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">In the following months, I\u2019ll write about bounds safety, type safety, lifetime safety, initialization safety, and \u2014 as a special add-on \u2014 about undefined behavior. And I will demonstrate that with very little effort, you can avoid all of these safety problems easily and by default.<\/p>\r\n<p>&nbsp;<\/p>\r\n","protected":false},"excerpt":{"rendered":"<p>In the first part, we saw how hard it is to be certain that loop-based C++ code is correct. Now Klaus presents the modern solution, a single algorithm call that is correct by inspection, and explains why the real problem in our community is an educational one, made worse by AI tools that keep generating classic C++.<\/p>\n","protected":false},"author":30,"featured_media":11473,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[567],"tags":[466],"class_list":["post-11471","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\/11471","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=11471"}],"version-history":[{"count":3,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/11471\/revisions"}],"predecessor-version":[{"id":11479,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/11471\/revisions\/11479"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/11473"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=11471"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=11471"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=11471"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}