My introduction to C++ came sometime around 1995. Raw pointers, manual memory management, debugging sessions that stretched into the small hours chasing memory faults. I wouldn’t have traded it for anything.

Fast forward thirty years, and I’m still reading C++ code regularly, embedded systems, backend infrastructure, and computationally demanding applications like 3D rendering. The language isn’t fading. The world depends on software that predates some of the engineers now maintaining it, and that software holds up. It’s been through the wars, squeezed for every cycle, and nobody’s in a hurry to replace it.

That’s not a criticism of the industry. It’s what longevity actually looks like.

Recently, I was inside a C++ codebase doing a proper audit. The familiar patterns were all there: memory leaks, threading models that weren’t built to scale, a few spots where the wrong input would produce a segfault, and nobody had found it yet. None of that caught me off guard, and none of it means the codebase is poorly written. This wasn’t legacy from neglect, it was an intentional choice, the right language for the problem. Those rough edges aren’t indictments of C++; they’re the trade-offs you accept knowingly when the domain demands it. And honestly, dropping back into C++ felt like coming home. That familiarity is something that doesn’t go away.

But there’s a conversation worth having about new work, should this be C++ or newer languages such as Rust or Go:

  • When Rust earns its place: Safety-critical contexts where a memory bug isn’t just a bug, it’s a liability. Systems where you need C-level performance and cannot afford undefined behaviour. Networked services where patching is slow and a vulnerability has serious consequences. Greenfield teams that have the runway to climb the learning curve properly.
  • When Go is the sensible choice: Services, infrastructure, and tooling where shipping speed matters more than squeezing out every nanosecond. Strong concurrency without the complexity overhead. APIs and data pipelines where the bottleneck is somewhere other than the language itself.
  • When C++ remains the correct answer: You have a proven, mature codebase where a rewrite introduces more risk than it resolves. Your team knows the language deeply, and the domain doesn’t offer a realistic alternative. Platform SDKs, performance ceilings, or the nature of the problem itself rule out other options.

The rewrite question is almost never really about the language. It’s about risk, cost, and team capability. I’ve watched Greenfield Rust migrations stall because organisations underestimated the ramp-up time. And I’ve seen plenty of C++ codebases run perfectly well for years on disciplined C++17/20 practices without anyone ever needing to reach for something newer.
Know your tools. The right language depends on the problem, not the trend.

What’s the oldest C++ codebase you’ve worked in? I’m always curious how deep that rabbit hole goes.

If you have C++, Rust, or Go code that needs a proper audit, that’s squarely in my wheelhouse. Let’s talk.

 

Also as a bonus:

When Python makes sense: You’re in the data science, ML, or scientific computing world where the ecosystem, NumPy, PyTorch, scikit-learn, Pandas, is simply irreplaceable. Your team moves fast on prototypes that need to become real things without a rewrite tax. You’re gluing systems together and the bottleneck is never the language. Scripting, automation, and tooling where readability and maintainability matter more than throughput.