June 2018: C++ Standard Proposals for Rapperswil Meeting

Welcome to the June 2018 edition of the Embedded Artistry Newsletter! This is a monthly newsletter of curated and original content to help you build superior embedded systems. This newsletter is intended to supplement the website and covers topics not mentioned there.

This month we'll cover 5 C++ language proposals that will impact embedded developers.

C++ Standardization Meeting in Rapperswil

Today marks the start of the C++ standardization committee meeting in Rapperswil, Switzerland. Developers from around the world will meet and work on the future of the C++ language.

C++ is complex, widely adopted, and must meet the needs of developers of all varieties. There are always competing priorities and needs, and it is up to the standardization committee (and an array of special interest groups) to ensure the proper balance is met.

I want to share five C++ proposals which are of interest to embedded systems developers. It may be years before we see these proposals in a formal C++ standard (if they are adopted at all), and the proposals should be expected to evolve with feedback from the standardization committee.

Even though they may be years out, these ideas can still benefit you today. Many of the proposals have corresponding testing libraries enabling you to try out the new features in your own programs. It's also exciting to take a look under the hood and see what future language changes are being discussed.

The proposals we will review are:

  1. P0709R0: Zero-overhead deterministic exceptions
  2. P0829R2: Freestanding
  3. P1028R0: status_code and standard error object
  4. P0037R5: Fixed-point real numbers
  5. P0132R1: Non-throwing container operations

For more on the Rapperswil meeting:

P0709R0: Zero-overhead Deterministic Exceptions

The Zero-overhead Deterministic Exceptions proposal is a potential game-changer for the C++ language.

The opening of Herb Sutter's proposal states that over 50% of C++ developers report that exceptions are banned in part or all of their code. As an embedded developer, I fall into both the partial- and complete-ban categories on my systems. Since exceptions are required to use many core C++ language features (e.g. constructors), this means that a large number of C++ programs are written in non-standard C++ dialects.

This proposal aims for a re-conception of the C++ exception model with two primary goals:

  1. Remove all technical reasons for a C++ project to disable exception handling
  2. Facilitate re-unification of divergent error reporting styles

The primary method of achieving the two goals is to annotate functions with the throws keyword, indicating that the function throws a statically specified type by value. Exception handling implementations can then be as efficient and deterministic as a local return-by-value, incurring no dynamic or non-local memory overhead.

How can this be accomplished? By ensuring that the only type of exception that can be returned is a std::error exception (discussed below in P1028). If the function fails, it will throw the std::error object as-if returning an alternate return value on the stack. Two additional possibilities are returning errors in unused processor registers and repurposing unused CPU flag bits to indicate whether the registers contain a return value or error.

The new exception mechanism provides two return paths for a function: one for the success case, and one for the failure case, where failure returns an error code as usual. The resulting API designs will be greatly simplified: no longer will error codes monopolize our return value channels, and users can't forget to check errors.

Those interested in trying out the new exception model are in luck. Niall Douglas has published the Outcome 2.0 library, which is effectively a library-only implementation of Herb's exception proposal.

For more on Zero-Overhead Deterministic Exceptions:

P0829R2: Freestanding

The Freestanding C++ proposal is one of the most interesting for the embedded world. Ben Craig is interested in identifying a subset of the C++ language which is suitable for kernel and embedded development.

The core goal is to enable developers to easily identify features which can be implemented without an OS. This is currently impossible with the existing standard, and many teams simply maintain a manual list of features which cannot be used in an embedded environment.

The paper identifies a working list of functions from existing headers (such as <cerrno>, <cstring>, and <algorithm>) which are allowed in a freestanding environment. The paper also identifies new headers which will need to be added and clearly outlines featuers which are not being considered for the freestanding subset.

Even if a Freestanding C++ is never formalized, the paper serves as a starting-point for features that are safe to use in an embedded environment. I will update the Embedded Artistry libc to incorporate some of the freestanding proposal notes.

For more on Freestanding C++:

P1028R0: status_code and standard error object

The standard error object proposal is a key component of Zero-Overhead Deterministic Exceptions. Even better, this proposal is compatible with the Freestanding C++ proposal, so all of the features can be used standalone on embedded systems.

This proposal covers the replacement of the <system_error> header with a lighter-weight and portable design. We also get a new std::error type with the following properties:

  • Always indicates a failure (no more "0" success codes)
  • No default construction
  • No empty state possible
  • Trivially copiable
  • Small enough to return in CPU registers (current proposal uses two pointers)
  • Portable across domains & operating systems

All operations which can be constexpr have been updated to be so, and the rest have been made literal or trivial to the maximum extent possible. Header-only libraries will now be able to safely define custom error code categories (you'll be unpleasantly surprised if you try this today). We can finally drop the if(!error_code) model, opting instead for a clearer if(ec.success()) or if(ec.failure()) check.

If you are interested in trying out the proposed status_code and std::error changes, you can try out Niall's status_code library. The Outcome 2.0 library, which demonstrates the exception proposal, also integrates the status_code support.

For more on the error code overhaul:

P0037R5: Fixed-Point Real Numbers

Fixed-point numbers are common in embedded systems for a variety of reasons:

  • Some systems don't have floating point support
  • Floating point support is often not thread-safe unless properly protected
  • Many external components communicate using a fixed-point format
  • The system may need to convert a number to fixed-point before sending the value out over a communication bus

Because there is no standard option available, developers are required to spin their own implementation or import one of the many fixed-point mathematics libraries.

Rather than treating fixed-point numbers as a special case, this P0037 proposes a drop-in integer replacement with fixed-point support. After all, an int is simply a fixed-point number with an exponent of 0. An API with the necessary fixed-point arithmetical tools will be provided by the standard.

John McFarlane's Compositional Numeric Library, which serves as a proof-of-concept for both P0037 and P0554, contains an in-development implementation of the proposed fixed_point class template. If you need fixed-point operations in your next project, give it a try.

For more on Fixed-Point Real Numbers:

P0132R1: Non-throwing container operations

As we covered earlier, many C++ projects operate with exceptions disabled. This is a problem since many of the standard library features are built around exceptions, especially allocators and constructors. If exceptions are disabled and an allocation fails, your program will typically end up in the abort function, which prevents any chance of error recovery.

P0132 proposes to create container operations which will not throw an exception on failure. The proposed additions to the standard are:

  • Allow an allocator to fail without an exception
    • Add a separate function for non-throwing allocation which returns nullptr on failure
  • Add a non-throwing reserve operation to vector and string
    • This would utilize the support for allowing an allocator to fail without an exception
  • Add a non-failing push_back to vector and string
    • Pushing without sufficient capacity will be undefined behavior
  • Add a push_back that can fail to vector and string
    • This function will report an allocation error, but will do so without an exception
  • Add a push_back that can fail to vector and string
    • This function will have no effects if allocation fails, and will not throw

As an embedded C++ developer, I would love to see these features and look forward to improved container operations in the coming years. I haven't yet seen a library to test such support, which means you will need to modify your local libc++ implementation to try these features out.

For more on Non-throwing Container Operations:

Around the Web

Watch John Regehr's closing keynote from C++Now 2018: Undefined Behavior and Compiler Optimizations.

GitNStats is a tool for analyzing how often particular files are modified. By identifying files with a lot of churn, you identify potential problem areas in your code base.

Jacob Benigo postulates on the soon-to-be-extinct embedded software engineer.

Sensirion recently announced the SDP3x differential pressure sensor family, which they claim is the world's smallest differential flow sensor.

Microsoft has announced Vcpkg, a C++ library manager for Linux, macOS, and Windows.

Website Updates

The For Beginners page has been reorganized, and a table of contents has been added.

The Hardware References page now has a table of contents. I also added Circuit Cellar's compendium of quick prototyping solutions.

The Software References page has been reorganized and a table of contents has been added. Paul Watt's blog was added to the software blog list.

New Articles

These articles were published on our website in May:

These were our most popular articles in May:

  1. Circular Buffers in C/C++
  2. Installing LLVM/Clang on OSX
  3. Jenkins: Configuring a Linux Slave Node
  4. std::string vs C-strings
  5. Jenkins: Running Steps as sudo
  6. A Simple Consulting Services Agreement
  7. An Overview of C++ STL Containers
  8. C++ Casting, or: Oh No, They Broke Malloc!"
  9. Implementing an Asynchronous Dispatch Queue
  10. Creating and Enforcing a Code Formatting Standard with clang-format

Thanks for Reading!

Have any feedback, questions, suggestions, interesting articles, or resources to recommend to other developers? Simply reply to this email!

While you wait on the next edition, check out the website or follow us on Twitter

Happy hacking!