Edited by humans. Written by AI. How our editing works
All articles

Why Your C++ Code Is Secretly Unmaintainable

Klaus Iglberger's workshop preview reveals how dependencies and coupling quietly transform simple C++ codebases into nightmares nobody wants to touch.

Marcus Chen-Ramirez

Written by AI. Marcus Chen-Ramirez

March 27, 20265 min read
Share:
Retro-styled conference poster advertising Klaus Iglberger's C++ Software Design workshop on April 30th for £345 or £90 for…

Klaus Iglberger wants to show you the most boring example imaginable. In a preview for his upcoming C++ software design workshop, he walks through the kind of code that makes experienced developers physically uncomfortable—not because it's wrong, exactly, but because it feels wrong in ways that are hard to articulate.

The example: drawing shapes. Circles, squares, maybe some rectangles. About 200 lines total. A shape enumeration, a base class, some inheritance. The code works perfectly. It compiles. It runs. Three shapes appear on screen, beautifully drawn.

And that's when Iglberger asks the question that ruins everything: What happens when you add a rectangle?

The Innocent Line That Breaks Everything

Adding a new shape type looks trivial—one line in an enumeration. But that single line triggers what Iglberger calls an "avalanche of changes." First, you need access to the enumeration itself. If it's in a library, you're already stuck. You can't extend without modifying, which violates the open-closed principle everyone claims to follow but rarely does.

Then comes the ABI break. The compiler might change how it represents the enumeration. Everything that touches shape types—which in this architecture is basically everything—has to recompile. Circles recompile because you added rectangles. Squares recompile because you added rectangles. None of this makes any sense, but here we are.

But the real problem lives in functions like drawAllShapes(). In Iglberger's example, it's a switch statement that asks each shape what it is, then casts it to the appropriate type. To add rectangles, you hunt down every one of these switches across your codebase. In a 200-line demo, that's annoying. In a million-line production system?

"How many switch statements would I have to change?" Iglberger asks. "50? Perhaps 100 or perhaps even 200?" He pauses. "Imagine the pull request: 200 touched files."

Nobody wants to do that. Which means, functionally, nobody will do that. The code becomes frozen not because it's perfect but because changing it is too expensive.

The Dependency Trap

Iglberger, who's spent 20 years doing C++ and nearly a decade as a trainer, argues that dependencies are the core problem in software design. Not algorithmic complexity, not performance bottlenecks, not even bugs—dependencies. Kent Beck, who invented test-driven development, agrees: "Dependency is the key problem in software development at all scales."

The chain reaction works like this: Code changes. That's inevitable, even for things you swore would never change. But when things depend on each other, one change cascades into ten, then a hundred. Dependencies make modifications harder, sometimes so hard that teams simply stop modifying code. They work around it instead, adding layers of cruft that make the next change even more expensive.

Dependencies also kill testability. When everything depends on everything else, you can't test components in isolation. The tests that should give you confidence become impossible to write. Dependencies obstruct modularity—you can't reuse code that's tangled up with other code. And they demolish build times. If changing an enumeration triggers a 15-minute recompile, techniques like test-driven development become theoretical luxuries rather than practical tools.

Scott Meyers wrote about this decades ago in More Effective C++: "This kind of type-based programming has a long history in C. And one of the things that we know about it is that it yields programs that are essentially unmaintainable."

Unmaintainable. The word every developer fears and most codebases eventually become.

What Modern C++ Actually Offers

Iglberger's workshop isn't about pointing out problems—that's the easy part. It's about showing how modern C++ provides better tools for managing dependencies. Not perfect tools, because this is genuinely hard. "I would argue that this is exactly the most difficult thing in software that we have to deal with," he says.

The workshop covers classic Gang of Four patterns—Visitor, Strategy, Prototype—but not as historical artifacts. Iglberger demonstrates how modern C++ features transform these 30-year-old patterns into something clearer, faster, more maintainable. The language has improved. The implementations should too.

Value semantics gets particular attention. Many of modern C++'s improvements come from taking values seriously, which sounds abstract until you see how it simplifies design problems. Then there's type erasure, which Iglberger calls "really really amazing"—useful both for design reasons and performance reasons, though those often turn out to be the same thing.

The workshop also touches on external polymorphism, a technique that lets you add polymorphic behavior without modifying existing classes. It's the kind of solution that feels like cheating until you realize it's just good architecture.

The Fundamental Guideline

Iglberger's central principle: minimize coupling between software components. At every level—modules, classes, functions. This isn't new wisdom. It's advice that's been repeated for decades. The hard part is actually doing it.

"Try to minimize coupling," he says, emphasizing the word try. Because it is difficult. Often very difficult. Sometimes you'll fail. But the alternative—letting dependencies run wild—produces those million-line codebases where adding a rectangle requires touching 200 files and nobody wants to change anything anymore.

Iglberger never claims his workshop will make this easy. He's not selling a silver bullet. What he's offering is a clearer map of the terrain, better tools for the journey, and the hard-won knowledge of someone who's been writing C++ since before many current developers started programming.

The shapes example is boring on purpose. It has to be. When examples get complex, you can't see the design problems—you're too busy understanding the domain. But circles and squares? Everyone gets those. Which means you can focus entirely on why that innocent-looking code makes you uncomfortable, and what to do about it.

Pete Goodliff wrote in Becoming a Better Programmer: "Nothing is set in stone. No code is sacred. Everything changes." If that's true—and it is—then the only reasonable response is building systems that can actually handle change. Not systems that resist it until they shatter.

More Like This

Four podcast panelists discuss the 2026 Security Intelligence Threat Intelligence Index against a backdrop of bookshelves…

Why Hackers Are Ditching Stolen Passwords for Apps

Public-facing app exploits surged 44% while credential theft dropped. IBM's new threat report reveals what's driving the shift—and why it matters.

Marcus Chen-Ramirez·8 months ago·6 min read
A hand points at a MacBook displaying the M6 Max chip logo with a glowing neon frame against a vibrant purple gradient…

Apple's Touchscreen MacBook Reverses Steve Jobs' Vow

Rumors suggest Apple's M6 MacBook Pro will add touchscreen capability—contradicting Jobs' famous stance. What this means for the Mac-iPad divide.

Marcus Chen-Ramirez·8 months ago·7 min read
Klaus Iglberger presenting at Meeting C++ 2025, with title text overlaid on a dark cityscape building background and…

C++ Safety: Balancing Performance and Security

Explore C++ safety issues and modern programming practices to enhance security without compromising performance.

Sarah Mitchell·10 months ago·3 min read
Two men from freeCodeCamp discuss why developers are returning to terminal-based tools, with quote text overlaid on a dark…

Why Code Maintenance Is Harder Than Anyone Admits

Oh My Zsh creator Robby Russell on the real cost of technical debt, why rewrites fail, and what 99% of developer time actually looks like.

Rachel "Rach" Kovacs·8 months ago·5 min read
Astronauts in space with Earth below, one pointing a gun, with nested meme frames about PowerPoint and repetitive questions

Decoding Core Dumped: Insights from George's Q&A

Explore Core Dumped's George on video creation, programming, AI's role, and computer science learning. Discover insights for developers and tech enthusiasts.

Marcus Chen-Ramirez·10 months ago·3 min read
C++ code snippet showing enum with bitwise OR operation, questioning whether the implementation approach is correct

C++ APIs: Lessons from Code Review at CppCon

Explore modern C++ API techniques with Ben Deane's insights from CppCon 2025.

Mike Sullivan·10 months ago·4 min read
Hugging Face ML Intern Automates AI Development

Hugging Face ML Intern Automates AI Development

Hugging Face's ml-intern is an open-source agent that automates the full ML research loop. Here's what it does, what it can't, and what it signals.

Marcus Chen-Ramirez·3 months ago·7 min read
Small Language Models Are Reshaping Agentic AI

Small Language Models Are Reshaping Agentic AI

Small language models are outperforming larger rivals on key AI agent benchmarks. Here's what the efficiency shift means for how AI gets built and deployed.

Marcus Chen-Ramirez·3 months ago·7 min read