Ask Slashdot: How To Start Reading Other's Code?
BorgeStrand writes "I'm reviving an open source project and need to read up on a lot of existing code written by others. What are your tricks for quickly getting to grips with code written by others? The project is written in C++ using several APIs which are unknown to me. I know embedded C pretty well, so both the syntax, the APIs and the general functionality are things I wish to explore before I can contribute to the project."
Knowing the data structures gives you the ground work for understanding what the code is doing. The data structures are a more direct description of the design decisions.
What are your tricks for quickly getting to grips with code written by others?
For me, it comes down to a lot of mountain dew, techno music, and hours of guru meditation. As you dissect each function, sketch out its relationship to other major functions. I take a two pass approach .. first, just look at the function call outs and the return values and make a rough sketch of the 'scaffolding' of a program. On the second pass, any function that you can't see the obvious application of, or appears obfusciated or complicated, dissect into functional units and sketch out what it does in your notes. I do this by actually physically drawing the relationships using something called a mind map.
Until you get used to it, actually writing it down, even if it's just a bunch of messy arrows to blobs of circled text... it will help job your memory and help things sink in until you have the necessary 'ah ha!' moment.
YMMV.
#fuckbeta #iamslashdot #dicemustdie
The trouble with university education, is that most people who teach there are computer scientists, not software engineers with years of experience in the trenches.
If this were actually the case, there would be a recognition that reading code is far harder than writing it. And far more emphasis would be on coming to grips, understanding, and working on large code bases. There'd be more stuff on things like unit testing, breaking dependencies, troubleshooting, and refactoring at least.
2) Just because the code is awful doesn't mean it has no value -- No matter how bad it is and how difficult it is to read, if it works at all it has probably got years (maybe even decades) of bug fixes and feature requests. Until you have a handle on it, any little change could cause a catastrophic cascade of side-effects.
3) No, we don't need to rewrite it. See 2. A working program now is worth more than all the pie in the sky you can promise a year from now.
4) It takes 6 months to have a reasonably good grasp of any moderately complex in-house application. It could be a year before you get to the point where someone can describe a problem and you immediately have a good idea of where in the code the problem is occurring and what functions to check.
Maintenance programming is as much about detective work as anything else. The only clues you have about the previous programmer are his source files. Once you've read them for a while you can start to tell what he was thinking, when he was confused, when he was in a hurry. Most of the atrocious in-house applications have changed hands several times and each programmer adds their own layer of crap. You can redesign these applications a chunk at a time until nothing remains of the original code if it's really bad, but it's best to save really ambitious projects until you understand the code better. I heartily encourage the wholesale replacement of "system()" calls with better code immediately, though. In several languages I've run across these calls to remove files, when they could have simply called a language library call (Typically "unlink".) If the original programmer used system("rm...") you can pretty much assume that they were a bad programmer and you're in for a lot of "fun" maintaining their code.
I'm trying to teach myself to set people on fire with my mind... Is it hot in here?
No, unit tests are a good idea. They wouldn't be my first choice, but they're a good option when deciphering a particularly difficult project.
(1) It gets you to interact with the code. This is always a good idea when leaning how something behaves. Fiddle with it for a while and see if you can figure it out.
(2) The unit tests don't need to be particularly true to their original requirements to be useful. When you do eventually start making changes, the law-of-unintended-consequences comes into play. If you make a change and one of your unit tests starts failing, then it will give you a clue that things may be interacting in a way that you did not anticipate.
I won't join Slashcott. OTOH, If Beta goes live, I just won't be back until it's fixed. Sorry Dice.