What is Well-Commented Code?
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."
I can absolutely recommend a book called Code Complete. Yes, it is published by Microsoft, but it is an invaluable language-agnostic guide to writing software that includes heavy doses of common sense regarding commenting, coding styles etc.
Tools like javadoc, or maybe better in your case doxygen can really help when it comes to commenting code... the idea is pretty much that you place a documentation comment before each function, or class, and so on, which usually makes the entire thing much easier. Having done that, I've found that only a few more non-obvious parts have to be commented within the actual functions.
Tomorrow will be cancelled due to lack of interest
*foo means 'foo dereferenced'. In a type declaration, 'int foo' means 'foo is an int', so 'int *foo' means 'foo dereferenced is an int'. And, therefore, foo is a pointer to an int.
So, it's actually quite logical. In this: 'char foo, *bar', we declare that two things have type 'char': foo, and the thing that bar points to.
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.
Tom Swiss | the infamous tms | my blog
You cannot wash away blood with blood
...who make reviewers like me stare at computer screens for endless hours trying to figure out how the hell your computer code is supposed to work.
// Creates hash table ". Question: Where does that leave me? When I find out that there's some problem in the hash algorithm, I have to dig through 200 lines of code to find some freakin' bug that is described only by "Creates hash table." Your example of why comments don't need to be made is a poor one:
// increment loop counter
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.
Take a look at these files. This project is basically an example of what not to do. It's faggotted up like a twelve-year-old schoolgir's notebook, to borrow a phrase from The Onion. In particular,
That should be obvious from the "public static void main (String argv[])".
What you are describing (and quite well) is the top-down programming practice. There's a big problem with it, though: in the real world, things change. As others have pointed out, you can't be guarenteed to be able to hammer down a specification that will be satisfactory for a year, or a month, sometimes even a week or a day. Some customer, some manager, or whoever, will demand a change in the final product. What will you do then? You will have to change your entire structure around and that can be extremely difficult.
Fortunately there are other ways of approaching the problem. One of them is called the bottom-up approach. The basic idea is to create a mini-language that one can better formulate your problem in, and then start putting the pieces together. This is complimented by dynamic semantics that languages such as Common Lisp or Smalltalk have. Incremental, interactive compilation and development is well supported by these environments. The code winds up being self-documenting because you wrote it in a mini-language! Weirdly obfuscated--but necessary--as well as commonly used pieces of code can be abstracted with Lisp macros. Changing your data-structures is no problem, already in-use data-structures can be dynamically updated (and you can control how it happens). Errors are handled by the exceptional condition system (no pun intended) and the program can be continued from where you left off, after being fixed. Always you have a working, running codebase.
Those who do not know the past are doomed to reimplement it, poorly.