Quest1
← perspectivesEngineering Practice
Engineering Practice

C++ in 2026: A Language That Talks Modern, Ships Legacy

or: how "import std;" — chapter 1 of a good book — turned into a rabbit-hole of building LLVM from source. C++'s specification has kept pace with modern ideas, but it's bolted onto a tooling ecosystem that hasn't — and beginners pay for that gap with a nightmarish developer experience

c++ tourofc++ developerexperience toolchain ecosystem

The setup

I picked up Bjarne Stroustrup's A Tour of C++, targeting C++23. The second program in chapter one — not some advanced corner of the language, the second program a newcomer sees — introduces modules:

import std;

Clean. Modern. The kind of thing that makes C++ look like it finally shed forty years of preprocessor baggage.

It doesn't compile. Not on GCC. Not on the Clang that ships inside a fully updated Xcode on a fully updated macOS. To get it running I had to:

  • Discover, through scattered forum posts and issue trackers rather than any official source, that working import std; support lives specifically in upstream LLVM Clang 23.1.1 — not Apple's fork, not GCC.
  • git clone --branch llvmorg-23.1.1 --depth 1 the LLVM project and build it from source, because the prebuilt Clang didn't cut it either.
  • Upgrade CMake to 3.31.5, because the version Xcode 26.5 ships is too old to drive the build.
  • Learn enough CMake + Ninja to hand-write a CMakeLists.txt that produces std.cppm/std.pcm — the precompiled standard library module — before main.cpp would even link.

I got through it only because I already had years of prior C++ scar tissue. Someone encountering this as their first systems language would have probably quit at step two.

So what went wrong

It's worth separating my complaint/rant into its actual pieces, because they have different causes and different people to blame:

1. The standard shipped years ahead of usable implementations. C++20 standardized modules; it's now well past C++23 and mainstream toolchains still don't have full, reliable, cross-vendor support. This isn't like a beginner forgetting a semicolon — the feature the book teaches as canonical, idiomatic C++23 is not reliably available on the machines beginners actually own.

2. There is no reference compiler and no reference build system. ISO C++ standardizes language and library semantics. It says nothing about how you invoke a compiler, how translation units get discovered, or how a package gets fetched. Every other layer — build system, package manager, module dependency scanning — is left entirely to a fragmented ecosystem of vendors (GCC, Clang upstream, Apple's Clang fork, MSVC) who move at different speeds for different commercial reasons. Modules made this worse than any prior feature because, unlike #include, they require the build system to scan module dependencies before compilation even starts. A feature that used to be "just the compiler's problem" became "the compiler's problem and the build system's problem," and the build-system side lagged for years.

3. Apple's Clang is not upstream Clang. Xcode's Clang is a fork, and Apple has never prioritized tracking upstream feature-for-feature — it optimizes for Apple's own platform and ABI concerns. "I downloaded the latest Clang and it still didn't work" is, unfortunately, an entirely predictable outcome once you know this, but it's completely opaque to anyone who reasonably assumes "Clang" means one thing.

4. The books and the tooling live in different timelines. A Tour of C++ is written to the aspirational standard — how the committee intends the language to look once implementations catch up. That's defensible as a language reference. It's indefensible as a first program a beginner types in, with zero caveat that the toolchain underneath won't cooperate for another year or two on their platform.

Why this actually matters, not just as a gripe

Compare the on-ramp to Go or Rust, languages in which I had zero experience five years ago — and that's the point. rustup gives you compiler, package manager (Cargo), and build system in one command, and the first cargo run on a fresh machine just works, on any OS, on day one, for any published crate. Go is even more aggressively single-toolchain. Neither ecosystem asks a newcomer to reason about which fork of which compiler, which version of which build generator, or how to hand-produce an intermediate artifact (.pcm) that the language's own tutorial never mentions exists.

C++'s strength — that no single vendor controls it, so no single company can capture or kill it — is inseparable from its weakness here. Openness plus zero central authority over tooling means every "modern C++" feature ships as language spec first and unified developer experience maybe eventually, sometimes never (e.g. the still-nonexistent single blessed package manager, decades after C++ needed one as badly as Rust needed Cargo).

The cost isn't abstract. Every beginner who hits this wall and doesn't have prior C++ background concludes "C++ is broken" and leaves for Rust, Go, or just Python — not because the language modules feature is bad (it genuinely improves compile times and encapsulation once it works), but because the path to trying it is an unadvertised systems-programming side-quest. Stroustrup and other advocates get to talk about modern C++'s strengths on forums precisely because they're advocates who already cleared this hurdle years ago and don't remember it as a hurdle. That's survivorship bias dressed up as language advocacy.

What "beginner-friendly" would actually require

Not rhetorical — concretely, closing this gap needs:

  • Version-gated documentation. Any tutorial teaching a C++20/23 feature should state, next to the code, which compiler versions and which build system setup are required to run it — the same way MDN flags browser support for a JS API.
  • A default build story for modules that doesn't require hand-rolling .pcm generation. This is squarely a build-tool problem (CMake, Meson) and it's improving, but "improving" three-plus years after standardization is still a failure of coordination, not a triumph.
  • Parity commitments from platform vendors, or at least honest labeling — Apple shipping a Clang fork under the unqualified name "Clang" without a loud version/feature-parity disclaimer actively misleads.
  • Someone — ideally the standards committee or a widely-adopted foundation — owning the "day one experience" the way Rust's core team treats rustup and Cargo as first-class deliverables, not community afterthoughts.

The bottom line

Calling C++ "beginner unfriendly" is generous. A more accurate description: C++ is a language whose specification has kept pace with modern ideas, bolted onto a tooling ecosystem that has not, sold through books written for a toolchain state that doesn't exist yet on most beginners' machines. Even if you're an intermediate-to-advanced level programmer in a different programming language, and it still takes frustration to go from-source LLVM build to run the second example in an excellent book - That's simply Bad Developer Experience. No sugar-coating here. That's an ecosystem's problem, and it deserves to be said plainly instead of drowned out by another "look how elegant concepts and ranges are" talk.

References

[1] Modules in libc++ - https://libcxx.llvm.org/Modules.html

[2] The LLVM Compiler infrastructure - https://github.com/llvm/llvm-project

[3] A Tour of C++ - https://www.stroustrup.com/Tour.html

[4] The C++ Standard - https://isocpp.org/std/the-standard

VI
Vishy Iyer
Author · Quest1
echo "let's connect"

Have a perspective of your own?

We'd like to hear how you're thinking about AI, data, and the architecture decisions that matter.