💾 Archived View for tilde.club › ~winter › gemlog › 2024 › 2-29.gmi captured on 2024-08-18 at 17:55:25. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2024-05-26)
-=-=-=-=-=-=-
You've just inherited a legacy C++ codebase, now what? (Hacker News)
I saw the linked article by Phillippe Gaultier on the Orange Site this morning, where he talks about what to do when you inherit a large C++ codebase. My interest was piqued, because this is how I actually started my career. It wasn't my first programming job (that'd be a multimedia app in Visual Basic), but my first technical job out of university was as a developer on a C++ codebase with over a million lines.
There were dozens of developers, so I was in no way alone, but there was no getting around that the application was massive. Not just C++, but also XHTML, JavaScript, XML, XSLT, some Java, a little C#. It had sort of accreted (as these things do), both slowly and quickly, over the previous sixteen years. It started off as a DOS-based C project, being converted to C++ a few years later. It had a bunch of different configurations to build a Windows app, a couple flavours of web app, some standalone servers for various functions...the #ifdefs were wild. My favourite horror: the function that took between 192 and 214 arguments, depending on the configuration.
The deeper you went into the codebase, the more you could see the layers. The newest stuff used std. Older code had a bunch of custom classes that were kind of horrifying/you never wanted to modify them, but the original developers were very, very good, so you never had to. And the oldest code was pure C: char*, void*, all that good (bad) stuff.
So anyway, this was my first programming job out of university. And I was curious to see how Gaultier's advice jived with my own experience.
1. Get it to work locally, by only doing the minimal changes required in the code and build system, ideally none. No big refactorings yet, even if itches really bad!
Yes, perfect, no notes. Get it to compile. Document how you did it. Ideally, at this point, delete everything, get it again, and test your notes. Compare this with your company's wiki equivalent. Update it if needed.
2. Get out the chainsaw and rip out everything that’s not absolutely required to provide the features your company/open source project is advertising and selling
Um.
Maybe this works on a project of fairly small complexity. But on the codebase I worked on, the other development teams would laugh you at the office at this point.
3. Make the project enter the 21st century by adding CI, linters, fuzzing, auto-formatting, etc.
100% agree, but this would be step 2 for me.
And unit tests! For C++, I've always used Google Test - it's pretty straightforward and easy to use, but there are lots of other good choices. Start by adding one test. You know the drill: make it fail, then update the test, and make sure it succeeds. One test isn't very many. But it's a start, and it's better than nothing. I've worked at places in the past that liked to talk about some unreasonable code coverage %, and expected you to somehow do this at the same time as working on a bunch of other Jiras. That's all but impossible if your C++ codebase is complicated. Again: start writing some tests. Make it part of your routine. I'm not advocating TDD (I don't like TDD, and feel like it sucks the essential joy out of the act of programming). Just adding useful tests where you think they're likely to be helpful down the line. You'll get a sense of this as you go along, too.
4. Finally we get to make small, incremental changes to the code, Rinse and repeat until you’re not awaken every night by nightmares of Russian hackers p@wning your application after a few seconds of poking at it
Yes. Once you've got it building, you should start with a very small change, ideally tracing through with your debugger to start to understand the program flow.
This part will take a while. Getting a mental model of how a complicated piece of software works can take literally years - my first CTO used to say it took developers several years to stop being dangerous on our codebase. He wasn't wrong.
If you have a mentor, see if they can walk you through a simple change, whether that's pair programming, or an implementation sketch, or similar.
5. If you can, contemplate rewrite some parts in a memory safe language
...I'm getting the sense that this hypothetical codebase isn't very complicated.
C++ is unsexy, even moreso now than when I started as a developer [mumblemumble] years ago. A rewrite of our codebase, at that time, would have taken, conservatively, at least half a decade. Absolutely a no-go. Some parts could probably have been split off; ironically, these were the newest, most modern parts of the codebase (the team I was on maintained them), and nobody was really concerned about them.
That said, even though parts of the codebase were varyingly chaotic and terrifying, there are a number of things we did do, and which I can happily recommend:
I'm where I am as a developer because I had an exceptional team lead for the first few years who taught me what it meant to be not just as a developer, but as a professional too. My first day, after I got set up, he assigned me my first task, and sent me a Word doc. This had, step by step, exactly what I needed to do to make the change, compile it, and test it.
Not everyone is so lucky. But it's something that's stuck with me. Not included in Gaultier's blog article highlighting refactoring, CI, linters, and so on, is the human element. How can you help your team succeed? Who else on your team is going to be working on this? Maybe you could work on something together. Start a Teams call, share your screen, load up Visual Studio. Go make a coffee then work through the change together. Step through the debugger, set watches, see what's going on. Remember that everything's hard when we first experience it, and nobody's born knowing anything. When you were just starting out, who helped you? Look around. Who can you help succeed?