Embedded C++ Series

SaferC++ Provides Safer Native Type Implementations

The SaferC++ library provides safer implementations for many native C++ types. The library provides features such as:

  • Data types that are designed for multi-threaded use and asynchronous access
  • Drop-in replacements for std::vector, std::array, std::string, std::string_view that provide improved memory safety
  • Drop-in replacements for int, size_t, and bool that protect against use of uninitialized values and sign-unsigned comparison issues (similar to type_safe)
  • Improved pointer & reference types with different compatibility and performance tradeoffs

SaferC++ is usable with embedded systems as long as your platform has a functional STL implementation. Exception behavior can be controlled for your platform by modifying the MSE_CUSTOM_THROW_DEFINITION macro.

Using the library does incur a performance penalty. However, SaferC++ elements can be disabled during compile time (i.e. replaced with the standard type equivalents). This allows users to enable debug and test builds to use safer-but-slower features without adding overhead to release builds.

Since the SaferC++ types provide added safety and can be disabled when performance matters, I highly recommend using their drop-in types to catch and eliminate possible errors when using STL types. The easiest way to get started with SaferC++ is to utilize the mse::vector and mse::array types in place of std::vector and std::array. These types will help you catch potential memory issues lurking in your software. The README provides further tips for making your code safer.

Further Reading

For more on SaferC++:

nothrow new: the Variant to Use When Avoiding C++ Exceptions

I'm a relatively young C++ developer, having spent the majority of my career programming in C. While I've devoted myself to the study of the language, I still frequently learn about new features and capabilities that surprise me.

I recently learned about nothrow new, a version of the new operator which returns a nullptr on failure instead of throwing an exception. While I have never seen this new operator usage in the wild, it's a valuable addition to my toolkit, as I often write embedded C++ programs without exceptions enabled.

In order to use the std::nothrow variants of new, you need to include the <new> header. Then you can overload new with std::nothrow:

int32_t* buffer = new (std::nothrow) int[100000000ul]; //non-throwing overload

If your system cannot allocate the memory, new will return nullptr rather than throwing std::bad_alloc.

Further Reading

A Warning When Using -fno-exceptions

As an embedded C++ developer, I typically write programs with exceptions disabled. My typical method for accomplishing this is by using the -fno-exceptions compiler flag. Unfortunately, I never realized a very important detail: even if I compile with -fno-exceptions, the C++ libraries I'm using have not been compiled with -fno-exceptions.

In order to be truly safe under this condition, I would need to avoid any standard library functions which might throw an exception, because they still will throw even if I cannot catch.

While some compilers, such as Keil, will correctly link a C++ library variant with exceptions disabled, this behavior is not guaranteed. If you are unsure whether a different library is being linked, I recommend compiling the C++ runtime with exceptions disabled. In this case, throw calls will be replaced with abort, which should be defined appropriately for your system.

Further Reading