Bloomberg engineers are constantly looking to help the C++ programming language evolve, while also providing backwards compatibility so that applications can be more easily written in an elegant way that’s simplistic, modular and concise, yet not over-engineered. At its core, C++ has some basic reflection capacity, as its code structure and behavior can be examined and modified at compile time. In other words, programmers can write powerful algorithms that operate in a generic way by inspecting types, functions, and their properties. This is frequently known as metaprogramming. Reflection is a new feature that works to fill in the gaps by fundamentally extending metaprogramming’s capabilities.
At the recent C++Now 2019 conference held May 5-10 in Aspen, Colorado, David Sankel, Software Engineering Manager and Team Lead at Bloomberg, delivered a keynote entitled “The C++ Reflection TS.” As an active member of the C++ standardization committee, David is currently serving as project editor for the Reflection TS, for which he is a co-author together with Matúš Chochlík of GlobalLogic Slovakia and Axel Naumann, member of the ROOT development team at CERN.
Reflection is a new language feature that enables code to read itself at a very broad level and make decisions for the code. Now, programmers can eliminate boilerplate from their code by standardizing these functions and declarations in a library that not just one piece of code, but all code in an application, can access. As a result, this consistency provides for fewer bugs and a smaller cost for repetitive tasks.
Sections of boilerplate code define parameters and syntax and provide minor functionality. These code snippets are often repeated multiple times because the language doesn’t otherwise allow for this functionality. With metaprogramming, repetitive boilerplate code can be eliminated through the use of templates. This allows functions to operate utilizing various data types without being rewritten. Metaprogramming is about writing a program that has knowledge of or can manipulate itself.
“Metaprogramming in this general form is pretty abstract,” he said. “In a specific form, if you’re making a generic class, like a vector class with units, what metaprogramming allows you to do is – depending on what you put on the inside – make certain choices like store things differently, like a vector of a bool.”
Vectors are specified by the type, like a vector of characters, strings of characters, or a template based on the type that’s given. A bool can be compressed, so what normally is stored in 8 bytes can be stored in only 1 byte. This is what metaprogramming makes possible. This functionality can be considered a basic form of reflection because it is introspecting the code at compile time and making decisions based on that code. The Reflection TS takes this functionality to the next level. Previously, a programmer couldn’t write a function with input that’s a type and output the name of that type, but the Reflection TS enables this – there’s now a mechanism to inspect data type declarations and function type declarations.
Having some data in memory and wanting to store it on disk or receive it over a network is common in programming. Serialization occurs when the in-memory representation is converted to a series of bytes and stored on a network. This feature allows for the conversion of that data into bytes without having to write code.
Learn more about the Reflection TS by listening to
David Sankel’s recent CppCast interview.
“The Reflection TS enables library developers to provide application developers with tools,” he noted. “It eliminates a lot of code, and the benefits are that there are fewer mistakes.”
Function writers who would make use of Reflection can now write very generic tools that can be used by different teams, and the teams can make use of these tools across many different domains. Maintaining code becomes easier because, if a field is added or a data type is changed, the UI is already up-to-date on these changes.
“You have a lot of consistency because it’s automatically generated – there’s consistency among developers or it’s the same developer over time – and it standardizes a portion of code,” he explained. “It’s a framework for writing similar extensions. We’re not shipping the individual functions. We’re shipping the tools that a library developer needs to develop those functions.”