Aussie AI

Chapter 1. Memory Safety

  • Book Excerpt from "Safe C++: Fixing Memory Safety Issues"
  • by David Spuler

Why Safe C++?

If you're a C++ programmer, then why are you asking? You already know all about the issues with C++ and its lack of memory safety. The only real question is why everyone suddenly cares.

There's really been two driving forces towards the need for a "Safe C++" language:

  • Large software companies, and
  • The U.S. Federal Government.

Large companies in the software development business, notably Microsoft and Google, have been complaining about C++ memory weaknesses for years. Notably, both Microsoft and Google reported the same percentage of failures attributable to memory safety issues: 70% of errors. These were mainly in the area of security, which is a subset of "safety," but the number 70% is so high that people started to pay attention to C++ memory issues.

Following on from this, several initiatives in the U.S. Federal Government cited memory safety as not just an economic issue, but also a security issue. Guidelines are available for the use of memory-safe programming languages, and C++ is definitely not on that list. This culminated in public releases from the White House with reports about memory safety in software.

Sounds like it's time to do something!

What To Do?

An important point to make is: this isn't the 1980s. Computers are massively faster than when the C and C++ languages emerged. Modern computers have the capability to defer more computational power to safety concerns without unduly reducing performance for users. Hence, whereas slowing down C++ for performance would have been anathema in decades past, it is quite plausible to do in the modern tech stack.

Hence, drawing attention to the memory safety issues in C++ is not unwarranted, and some would say it's long past time to do so. Reactions by affected parties to the White House materials were varied, and included:

  • Push to use Rust over C++,
  • Defenders of C++ emerged, and
  • The "Safe C++" initiative was launched.

It's not like nobody's ever done anything before. Indeed, those very same companies, Microsoft and Google, have done extensive work on their internal C++ software development practices. The whole industry has developed tools and techniques aimed towards higher quality C++ software in terms of memory safety and other quality concerns.

Notably, the recent high-level attention has also spawned a new initiative: the Safe C++ language proposal, which is connected to the ISO standardization organization. The idea of Safe C++ is to define an extension to the standard C++ language that incorporates additional safety capabilities.

This new proposal, which will hopefully evolve into an ISO-ratified standard, uses some advanced and brain-bending ideas. Many of these ideas are borrowed from Rust (surprise!), which has a model of memory "borrows" and "lifetimes" that can give a compile-time guarantee of memory safety, while not incurring the runtime cost of garbage collection methods.

Choices for Safe C++ Projects

Organizations are well aware of software quality issues, and their software development organizations already use many tools and techniques. Nevertheless, how should you respond to the Safe C++ initiative? At a high-level, the main choices are:

  • Switch — move to a memory-safe programming language (e.g., Rust),
  • Stay — do nothing different and keep using C++.
  • Wait — for Safe C++.

Note that Rust is not the only alternative to C++. There are other memory-safe languages, such as Go or Java, but these have the performance cost of garbage collection.

I'm not a fan of the Rust rewrite, mainly because I'm a C++ programmer. Thus, I have disclosed my bias. But most developers love a good rewrite, so they might be happy to learn a new programming language for that. The pay rates for Rust are higher at the moment, so there's that incentive, too.

Don't count on me to switch to Rust, but, on the other hand, as an experienced C++ programmer for multiple decades, I'm well aware of all the memory problems inherent to C++ programs. It's surprising the industry has taken so long to make it more of a priority.

People just like speed, I suppose?

The Safe C++ Proposal

This book examines the proposal for "Safe C++" from the C++ Alliance. This is an early working-draft proposal for extensions to the C++ language, intended to move towards an ISO standard for safer C++.

The first draft was released in September 2024, by authors Sean Baxter and Christian Mazakas at safecpp.org. The proposal includes an extensive document and a Github repository.

It is important to note that this is only a proposal at the time of writing. You should check whether anything more recent has changed in the C++ standardization area, although formal ratification of new ISO standards may take years.

Another area is that the industry C++ compilers, such as GCC, Clang, and Microsoft Visual C++, often lead in terms of adding new language functionality. These compilers already have significant safety features that can be used already, and more will undoubtedly be added over time, especially with the current interest in safer C++ practices.

The Pragmatic Plan

Are these your only options for addressing C++ memory safety: "stray, stay or play"? By which I mean, move to Rust, stay with standard C++, or "play" while awaiting Safe C++.

How about this for a fourth option:

  • Fix or mitigate as many C++ problems as possible now, and
  • Move to Safe C++ when available.

Let's do something pragmatic, right now!

There are incremental ways to partially address the C++ safety issue, instead of a massive dislocation (Rust), or doing nothing, And it sure beats just sitting around to wait for compiler vendors and the standardization organizations to finish their work on a new Safe C++ language.

There are many ways to proactively intervene now to improve the safety of C++ code. Some suggestions that we'll examine in this book include:

  • Use existing safety capabilities of compilers (there are many!)
  • Exploit all of the various toolchains for C++.
  • Run the memory debugging tools at full scale.
  • Use debugging libraries available already.
  • Use linters and static analyzers as another defensive method.
  • Adopt defensive C++ coding practices that prevent or mitigate against failures.

It's not like nobody's ever done anything about safe C++. Let's max it out!

Sliding Scale of Safety

There's not a binary distinction between "safe" or "unsafe" programs. Rather, there's a sliding scale where there is a trade-off between levels of safety and the runtime performance cost of achieving that safety. At the two ends of the scale are:

  • 100% safe — pointer accesses disallowed or in bubble wrap.
  • 100% unsafe — super fast, no checks at all.

Now, 100% memory safety is effectively achievable today, but it runs slow. I don't mean the Safe C++ language proposal, which would run fast, because we don't yet have that. Instead, I mean the well-known memory checker tools such as valgrind and the other various "sanitizer" tools, which effectively wrap all erroneous pointer and memory issues, and make them harmless, with a reported error message. Hence, we certainly can run C++ programs in a very safe way, just by using these tools that already exist.

These runtime memory checker tools are widely used by C++ developers during the testing and debugging phases. But we can't make our customers use these tools, because they'd be just too slow. Hence, the real question is not how to get C++ safety, but how to achieve C++ safety with acceptable speed.

The software development industry knows this issue only too well. There are a number of techniques to improve C++ quality as part of the software development processes. We already mentioned one of them, which is the regular use of sanitizers and memory checkers by developers. There are numerous other things that C++ coders do "in the lab" to improve code quality:

  • Unit testing and regression testing (i.e., automated testing).
  • Compiler warnings and linter tools that examine source code.
  • Standardized libraries and third-party code (i.e., reusing pre-tested C++ components).

The list is rather long, and we're going to examine various other ideas in later chapters. But here's the big question:

  What's missing?

The answer is simply there's no safety net when running C++ for customers. This book examines two main types of bubble wrap to use for running a C++ program:

  • Safe C++ language proposal — guaranteed memory-safety.
  • Dynamic safer C++ libraries — detect and make harmless a subset of problems.

Again, there's a sliding scale. The proposal for a Safe C++ language achieves memory safety with zero cost to run-time efficiency and an enforceable compile-time guarantee. The various other "safe C++ library" ideas can improve safety, but their effectiveness is on the sliding scale: simple error checks can prevent some memory failures, at a low runtime cost, whereas more comprehensive memory checking can prevent more errors, but at a greater slow-down in execution speed.

Organizational Safety Initiatives

Most of this book is down in the details of the C++ language, but that's not the only area to examine. At a high level, here are some company-wide actions that will improve C++ safety:

  • Hire experienced C++ programmers.
  • Train your existing C++ staff with a focus on safety practices.
  • Review existing C++ development practices from a safety perspective.
  • Ensure processes and project management are in place for software development.

With regard to processes for software development, some more specific ideas include:

  • Professionalize workflow with source code control, requirements and design, etc.
  • Document policies and practices related to C++ safety.
  • Define coding standards and risk areas with regard to safety.
  • Implement code review and CI/CD approval practices.
  • Consider safety-specific refactoring projects.
  • Don't expect AI to save you!

The reality is that C++ safety won't improve much unless you make it a business priority. Doing so is not without cost in terms of time and money, so you should also consider what you're going to de-focus away from in order to have time for a coding safety initiative.

 

Online: Table of Contents

PDF: Free PDF book download

Buy: Safe C++: Fixing Memory Safety Issues

Safe C++ Safe C++: Fixing Memory Safety Issues:
  • The memory safety debate
  • Memory and non-memory safety
  • Pragmatic approach to safe C++
  • Rust versus C++
  • DIY memory safety methods
  • Safe standard C++ library

Get it from Amazon: Safe C++: Fixing Memory Safety Issues