5 min read ·
Nobody picks C++ for fun
Nobody chooses C++. The machine, the latency budget or the SDK chooses it for you. This summer an SDK chose it for me.
I started a job in a university IT department in Chicago this month, and part of it is writing controllers against the Zoom Rooms Controller SDK. Zoom ships that SDK as a native C++ library. So the controllers are C++. That was the whole decision.
Trading firms that compete on latency write their engines in C++, because a garbage collector that pauses at the wrong moment is a trade somebody else gets. Unreal Engine is written in C++, so a studio that wants to change how the engine behaves writes C++ too. An Arduino sketch is C++ with the frightening parts hidden, and on an Uno R3 it runs in 2 KB of RAM.
The case against C++ is real. On February 26, 2024, the White House's Office of the National Cyber Director published a report called "Back to the Building Blocks" that urges technology manufacturers to adopt memory safe programming languages, and it names C and C++ as widespread languages that lack memory safety. It cites industry analysis showing that, in some cases, "up to 70 percent" of the CVE-assigned vulnerabilities in memory unsafe languages come from memory safety bugs, "despite rigorous code reviews". This is not a skill issue that a stern senior engineer can review away. The report's examples start with the Morris Worm in 1988 and end with the BLASTPASS exploit chain last year, with Slammer and Heartbleed in between.
Then read two pages further.
The report stops to consider space systems and lists what they need from a language: code that sits close to the kernel and the hardware, determinism so the timing of outputs stays consistent, and no garbage collector, or one you can override. It names the languages that pass.
At this time, the most widely used languages that meet all three properties are C and C++, which are not memory safe programming languages.
Rust has all three properties, the report adds, "but has not yet been proven in space systems." Take the word "space" out of that list. That is the requirements document for a trading engine and for a game loop. The report calls space systems "a unique edge case". Whole industries live in that edge case.
"Why not Rust?"
Show me the SDK.
Rust is a good language, and if Zoom shipped a Rust crate I would try it the same day. Zoom does not. I could write bindings, and then my "safe" program would be a thin layer of Rust wrapped around the same C++ library, joined to it by an unsafe boundary that I now own and that Zoom has never seen. Telling a company with a working codebase to rewrite it in Rust is correct advice in the way that flossing every day is correct advice. Most of the C++ that will run in 2034 is already written.
Bjarne Stroustrup called the first version of his language C with Classes. Much of what the report complains about is its descendant, C with regrets: raw new and delete, char buffers sized by hope, pointer arithmetic and C-style casts, written in 2024 as if 2011 never happened. C++11 gave the language auto, lambdas, move semantics, std::unique_ptr and std::shared_ptr. The committee has shipped a standard every three years since. C++23 is finished and waiting for ISO's stamp, and C++26 is under way.
Modern C++ is nicer to read. It is still not memory safe.
std::vector<int> v{1, 2, 3};
// C++98
for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it)
std::cout << *it << '\n';
// C++11
for (const auto& x : v)
std::cout << x << '\n';
// Also C++11. Compiles clean. Undefined behavior.
for (const auto& x : v)
if (x == 2) v.push_back(4);
The second loop cannot be off by one. Clang compiles the third one without a warning under -Wall -Wextra, and it is a use-after-free: push_back can reallocate the vector, which leaves both x and the loop's hidden iterator pointing at freed memory. AddressSanitizer flags it as a heap-use-after-free on the first run. The pretty syntax did not save that loop. Knowing what push_back costs would have.
For the next ten years, write C++ as if every line has to answer two questions: who owns this object, and what can invalidate this reference. Turn on AddressSanitizer and UBSan in every test build. Run clang-tidy in CI, and make your CMake setup turn all of it on by default so nobody has to remember. Reach for Boost or Qt before anyone writes a homemade thread pool. The tools are free, and there is a White House report on the desk. Skipping them is negligence, and it lands on users who will never see the code.
An SDK can choose your language. It cannot make you write C with regrets.
