Slashdot Log In
What is Well-Commented Code?
Posted by
Cliff
on Mon May 20, 2002 03:16 AM
from the inlined-internal-documentation dept.
from the inlined-internal-documentation dept.
WannaBeGeekGirl queries: "What exactly is well-commented code anyway? Can anyone suggest resources with insight into writing better comments and making code more readable? After about six years in the software development industry I've seen my share of other people's code. I seem to spend a lot of time wishing the code had better (sometimes _any_) comments. The comments can be frustrating to me for different reasons: too vague, too specific, incoherent, pointing out the obvious while leaving the non-obvious to my imagination, or just plain incorrect. Poorly or mysteriously named variables and methods can be just as confusing. In a perfect world everyone would follow some sort of coding standards, and hopefully those standards would enforce useful comments. Until then, any suggestions for what you, as a programmer, consider to be good/useful/practical comments? Any suggestions for what to avoid? Also, I usually work with C++ so any resources/comments specific to that language would be too."
This discussion has been archived.
No new comments can be posted.
What is Well-Commented Code?
|
Log In/Create an Account
| Top
| 826 comments
(Spill at 50!) | Index Only
| Search Discussion
The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
Re:Variable Names (Score:4, Insightful)
The same goes for 'amusing' comments in the code, or CVS logs.
For your sake in the future, and your coworkers' sake now, please stop it.
PS. Did I mention how fucking annoying it is?
Re:Variable Names (Score:5, Insightful)
Querying the DBs directly showed that the data maps were works of pure fantasy in several spots, or would lead to outright data loss if followed precisely. In a fit of pure...creativity...I ended up setting a "$workAroundFuckups" variable, and in the sections where it was needed, had a false evaluation do precisely what thee datamaps said, which would corrupt data. If the variable was true (ie, non-zero), it would work correctly, which meant ignoring the data maps and doing what was needed to have the data be entered correctly.
I ended up getting moved to another customer (due to the limited resources *we* had, not because of my creativity), so I don't know if the remaining folks on the project removed it after I left. When I added it, I explained to them precisely why I'd added it, and since they'd had similar experiences with what we were given to work with, were behind me 100%.
This wasn't even the *only* part of the project which was FUBARed, but it was unfortunately what I spent many a 15+ hour day dealing with, so I was rather familiar with it. Had I access to the server that *read* the data and used it, I probably would have just gone in and redesigned everything "for free", just to avoid having to deal with such a horrible layout.
This is also the client where, after a few months of an irksomely out of sync clock (off by 12 hours...made figuring out when something happened a bit of a PITA), I finally went in and set the damned clock to the proper time. Not surprisingly, the same folks who made that wonderful novel for us were the ones admining the dev server we were working on. AFAIK, no one ever noticed that the time suddenly became "correct" either.
Re:Variable Names (Score:5, Interesting)
Thing is, there's two essential things that a reviewer/maintainer has to understand about a program: what it does; and why it does it. It should be possible to work out the first one of these just from the code, so long as the variables and functions are named sensibly. The second can be worked out from code with some effort, or the coder can add comments to explain why they're doing things that way and make it easier for maintainers.
But if someone has deliberately given all the variables names which don't reflect what they do, then it's utterly impossible to work out what the code is doing, and it's therefore also impossible to work out why it's doing it. So the code is unmaintainable - it isn't possible for anyone else to pick it up and work out what it does, except with massive work. If in 6 months time your company says "oh, we've got this code we can use with slight modifications, let's quote 1 month to do this contract" and then they find out you've made the code utterly obscure, then they'll crash and burn. And if that happens, the company *will* fire (or at least formally discipline) the person who wrote the original code, bcos they've been grossly negligence in doing their job. And you can kiss goodbye to any reference from them, so you'll be SOL in finding your next job.
Grab.
Code Complete (Score:5, Informative)
Re:Code Complete (Score:5, Insightful)
Yes, that's on my bookshelf -- but, given the fact that they go to great lengths to point out the importance of checking for buffer over/under-runs and fencepost errors, one can't help wondering if (in the wake of all those critical bugs in IE/Outlook/IIS) any of Microsoft's own programmers have read it.
More "do as we say, not as we do" from Microsoft?
Re:Make the variable names mean something! (Score:5, Informative)
I strongly disagree. The proper delineation of a function or method is the operation that it abstracts, not how long it is.
If a subroutine is only called once, and doesn't cleanly abstract some idea (i.e., if you can't tell me what it does in one simple sentance), it should not be in a separate subroutine.
I've seen too much code written in the manner you suggest, that makes the reader bounce around from function to function to function for no reason other than "otherwise that function would be more than 30 lines".
If I have to maintain such code I always refactor it into one subroutine.
Describe before you apply (Score:3, Funny)
ie,
while (1) {
}
Multiple passes to your code (Score:4, Insightful)
One day you're commenting on what variables do, the next you try to explain functions, etc.
I just switched to Java from C++ and neatness is the most important thing I've acquired, not in code per se, but in variable naming. I've gotten used to doingThisWithVariableNames and DoingThisWithClassNames, while keeping THE_CONSTANTS capitalized. Ok, this isn't comments? But you'll be surprised at how much better it is to browse a new language like Java and see the norms of style in it, because old languages use too many confusing double_StandardslikeWritingThis_way.
Comments go at the top of a page, with the coder's name and date, as well as a small bug report and if you can, a brief function list for those without a visual IDE like JBuilder. You then put a like with PRE: and POST conditions in your code and try to keep one liner comments to a min.
I learned to comment the end of if structures and function blocks to make the code easier to follow... just add " }
Comments should be a paragraph long so that they make some sense. And comments, since they look different from the code sections, should be embelished with ===============, stars, and some
nice spacing and vertical bars.
Good comments to me mean good-looking comments, even if they don't have that much substance. Just my 2 cents. They're better than no comments at all.
Good Comments (Score:4, Insightful)
I then write inline comments in the code describing it's flow. It's only then do I actually write the code.
Comments at file/class level should describe what it does and is used for. It should also describe how it fits in with the big picture of it's packages and the classes around it - give a reader some architectual scope to what they're looking at.
Get into a habit, even for trivial functions/methods and you'll soon not realized you're doing it.
Some people say code shouldn't need commenting, and the code itself should be enough. In a perfect world of no bugs and only populated by wizard programmers, this is fine, but not in the world I live in. You write some code and someone else (maybe yourself) will have to debug it at some point - maybe 3-4 years down the line. Even with a "neat" language like Java, working out how things work is much more time consuming without comments.
Re:Good Comments (Score:4, Insightful)
Congrats, you've just described a maintenance nightmare.
Every time someone has to change some code, you've just forced them to double their workload, and change some comments too.
If they forget, or don't have time, or are lazy, or don't notice the comment (it's easy to blank them out) then the comment doesn't get updated.
Now you have a comment that is wrong. And that is so so so much worse than having no comment at all.
Comment sparsely. Do not sprinkle your code with comments. Especially do not use comments like
// increment loop counter
loopCounter++;
That is adding zero value.
Inline comments are a major headache - they're painful to write, painful to maintain, and dangerous if they aren't maintained.
~Cederic
Re:Good Comments (Score:5, Insightful)
I'll repeat that: they MUST change the comment. And it must make complete sense when they're done or they'll be out of a job!
Why is this important? When you change the comment, you must think about the comment. You must think about the change you've done and how it fits in with the rest of the code, and what the rest of the code is trying to do. If a comment isn't up to date or doesn't make sense, that's a bug in the code, as bad as any other, and it needs to be fixed.
It's not difficult to spot when the comments don't line up, so they're fairly easy to fix. While you're there fixing the comments you need to check the code, 'cos whoever the idiot was that wrote it, they obviously haven't checked it properly. Go and hit them with a Very Big Stick.
Certainly you shouldn't whine about the extra typing. A little extra typing shouldn't hurt - and you should be able to type faster than you can think, so it shouldn't really slow you down. If it does, go take a typing class.
And if your lame excuse is that you're in too much of a hurry to maintain comments, just make sure you're not in too much of a hurry to deal with the bug reports that come back because you haven't checked your code properly.
Re:Good Comments (Score:4, Insightful)
... and absolutely essential to the poor bastard who comes after you - without them he has zero chance. I spent some hours on the phone a couple of days ago talking some poor lad in the states through the trickier bits of one of my open source packages. Fortunately it is inline-commented, so I at least knew what I had been intending to do.
I agree with everything you say about the nuisance of maintaining comments, and I agree with everything you say about the problems that happen when you fail adequately to maintain comments. It's a chore; but it's a vital chore. It's got to be done.
It's sophomores like you... (Score:5, Informative)
Comment sparsely. Do not sprinkle your code with comments. Especially do not use comments like
Yea, I can already picture your programming style. You'd make a 200-line function with the only comment being "
loopCounter++;
That is adding zero value.
Yes, because it's one line of code, and the code is described through the variable. But when sifting through lines of code, you often find beautiful works like iHateMyJob++; or fuckMyBoss--; to name a few. And needless to say, they're uncommented in the code. Until computer code can be written bug free in complete English sentences (aka Never), the rest of your team of workers needs to understand what your code does.
Personally, I make sure every function says what goes into it, what comes out of it, and what setup (variables, etc.) need to be made for it to be called. I do not comment every single line of code, but I do make sure that every line is accounted for by descriptive sentences, explaining the task that I wish to accomplish as well as what variables / registers / actions I take to accomplish the task.
Every time someone has to change some code, you've just forced them to double their workload, and change some comments too.
Okay, this just pisses me off. You didn't mean what you said. Here's what you meant to say:
Every time I have to change some code, you've just forced me to double my workload, and change some comments too.
I can assure you, from a reviewer's point of view, comments SAVE my time from trying to understand what each piece of code is trying to accomplish. Commented code may make you work extra time to detail the lines of code (I do admit, some programmers are quite tallented at keeping track of every single line of code in their head as they work on it on the computer), but it saves tremendous amounts of time once that chunk of code needs to be integrated with other chunks of code into the final product.
Use plenty of expletives (Score:5, Funny)
// no fucking idea how this works
obj.doMagic();
or...
//bet those fucking lazy cunts in the QA team don't pick this up
fileSystem.delete();
When your code is released as open source and becomes famous, people can amuse themselves by searching through the source code to find all the hidden expletives, sort of like easter eggs. If you work for a commercial organisation, you can sit back and enjoy the panic as the QA and release teams sweat it out trying to track down every last filthy utterance before shipping to a fucker...errr..customer.
Re:Use plenty of expletives (Score:4, Funny)
Funny variable names are sometimes related to say specific bugfixes a certain individual or customer has demanded.
I know one person where very large customer demanded a specific and very idiotic new feature to the software, due to the customer being an idiot.
Executable was not stripped.
The variable name to control this feature in certain functions was thus called IsAFuckingIdiot
Customer by convention always ran nm on all new executables they installed.
Customer got very upset.
Doxygen, etc (Score:5, Informative)
Re:Simple rule of thumb (Score:4, Interesting)
Nice idea; never works in practice. The reason is that what you think is easy to understand is not always what other people think is easy to understand.
The code you are writing now might have to be modified in the future by someone just out of university which means, generally, someone with very little experience. Your red-black binary tree might be "easy to understand" for you and a novelty to them.
Also, mature highly-factored, optimised code that has been improved over several years can be very hard to follow even when the original code was quite straight-forward (but perhaps too slow).
Finally, as a philosophical point, source code is supposed to be terse in comparison to natural language so it should take longer to describe the code in your own language than in the programming language.
TWW
It's been a long time but.. (Score:5, Interesting)
First-up you need a good spec -- and the spec should include the user-interface details to the extent that you could actually write the user-manual from that spec.
Indeed -- if you can't write the user-manual from the spec then the spec is incomplete.
From the spec the programmer should develop the structure of the code in another document.
That structure document is repeatedly refined in a top-down process until you (eventually) reach a point where you're actually cutting code.
I was always surprised just how much easier it was when the code was written as the lowest level of the structure documentation.
Not only could you comment out the program structure document so that the compiler would ignore it -- but you ended up with absolutely accurate and comprehensive documentation built into that source.
Project managers love this technique (and when I was in a project management role I demanded it of my team) -- it ensures that technical and end-user documentation are no longer the bits that get left until last and thus are either very shoddily thrown together or, if the project goes really over-budget, not produced at all.
Of course, as we all know, there's a huge amount of temptation to just leap into coding at the earliest possible stage and leave the documentation until later -- because some stupid managers use number of code-lines completed as a metric of project performance -- duh!
If you're smart and use good tools you can selectively collapse and expand the in-source documentation so that when you're trying to get familiar with a module that someone else has written, you can descend down the structure tree one level at a time without the meaning being diluted by stuff that is at a lower level.
Unlike the days of interpreted BASIC, there's very little overhead involved in integrating documentation and code these days -- so there's no excuse not to do it.
If required, the documentation can be automatically extracted from the source -- but by keeping the master copy in the code it becomes easier to ensure synchronization as changes and updates are made during the lifecycle of the project.
Document the function's contract (Score:5, Interesting)
Take a look at this function, and tell me if there's a bug:
Easy, the bug's the SEGV, right? Take a look at the same function, this time with comments:
The point? A bug is unwanted behaviorm, but that only makes sense if you've defined what the correct behavior is. My example is trivial, but often this is a real concern. Function "bar(int,int)" returns null whenever one of the arguments is negative--is that a bug or a feature? Your function has a goal in life, a contractual obligation to do something; make sure it's clear what that something is.
Note that if you choose good function and good variable names, a simple one or two line comment at the beginning is usually sufficient to document whe function's intended behavior.
I also find that an "assert()" or two on the arguments at the top of the function makes it clear what values the function accepts, and which one the functi