Slashdot is powered by your submissions, so send in your scoop

 



Forgot your password?
typodupeerror
×
Programming IT Technology

What is Well-Commented Code? 826

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?

Comments Filter:
  • Per project (Score:2, Insightful)

    by mnordstr ( 472213 ) on Monday May 20, 2002 @04:25AM (#3548821) Journal
    I guess the only real solution is to give a specific coding standard for every project. Before you begin coding, make up a standard that every developer has to follow, for comments, code layout, etc.

    A good standard for C++:
    http://www.possibility.com/Cpp/CppCodingStandard.h tml [possibility.com]
  • Good Comments (Score:4, Insightful)

    by jamieo ( 22197 ) on Monday May 20, 2002 @04:26AM (#3548828) Homepage
    Good code comments should describe the intention of the code. Write them *before* you write the code in a function/method to describe it's purpose. This will make you think exactly what you want it to do, and will allow for others to find/fix bugs easier when the implementation doesn't meet the intention.

    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:Variable Names (Score:2, Insightful)

    by alpha1125 ( 54938 ) on Monday May 20, 2002 @04:38AM (#3548866)
    My variable names usually are forced into be changed after a code review by my peers...

    They don't have that funny bone, when the code is going to be in production software, and maintance by others.

    It's a professional image thing...
  • Re:Variable Names (Score:4, Insightful)

    by gazbo ( 517111 ) on Monday May 20, 2002 @04:39AM (#3548870)
    I experience code from others who have this problem, and frankly it pisses me off. Not meaning to flame you, but what seems creative and amusing at the time stays in the source, and becomes stupid and annoying later.

    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?

  • by fractaltiger ( 110681 ) on Monday May 20, 2002 @04:44AM (#3548889) Journal
    are the best way to comment it all.

    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 " } //end if" or something.

    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.
  • Re:Code Complete (Score:5, Insightful)

    by NewtonsLaw ( 409638 ) on Monday May 20, 2002 @04:44AM (#3548893)
    I can absolutely recommend a book called Code Complete [amazon.com]. Yes, it is published by Microsoft

    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?
  • by jon_c ( 100593 ) on Monday May 20, 2002 @04:48AM (#3548906) Homepage
    Personally I think the linux kernel is very well documented, at least the scheduling part, which is what I've looked at. Linus has a style of inserting huge comment blocks that explain exactly what's going on, then he'll have a page of code that does it, with little or no comments.

    A style suggested in Code Complete (I forget what they call it) is to write a method completely in pseudo code, make sure it's correct, then insert the actual programming code under each line of pseudo code. This technique, while clever I find leads to many useless comments like "loop through the employee records" and "increment the counter".

    A good test to see if the comments are working is through a code review, people will very often not know what's going on, or point out confusing comments or code that needs a better explanation. Code Reviews really improves your idea of what good comments are and teaches you what works and what doesn't.
  • Good commenting (Score:3, Insightful)

    by RockyJSquirel ( 412960 ) on Monday May 20, 2002 @04:55AM (#3548925)
    I wish I had time to go into more detail but I recommend:

    1. Every class should have a clearly defined public interface and documentation of:
    a) what the class is for and (if appropriate) why it was designed the way it was
    b) how it works
    c) how to use it
    d) how to extend it (if there's any reason to do so)
    e) it's lifetime / memory usage(if appropriate)
    f) if it's tightly connected to any other classes or functions, that should be documented
    g) how to make classes derived from it (if appropriate)

    2. Every function should have a comment that says:
    a) what it does
    b) why (if there's any question)
    c) what side effects it has (if any)
    d) what side effects it depends on (if any)
    e) if the functions is tightly bound to any parts of the program (it's not a context free sort of routine) then you should list where it's called from.
    f) examples of how its used (if appropriate)
    g) This one is important: describe the algorithm. It's important to keep this sort of comment up to date.

    I'm not so enthusiastic about comments on individual lines of code. They seem less necessary to me than the other sorts of comments, especially if everything is well named.

    I've been trying to get people at my latest company interested in code documentation, but I seem to have lost that battle. It's a shame. The only way to develop around here is to read every damn line of code, and that's unbelievably wasteful.

    Rocky J. Squirrel
  • Re:Variable Names (Score:5, Insightful)

    by emag ( 4640 ) <<gro.iksrug> <ta> <todhsals>> on Monday May 20, 2002 @04:58AM (#3548937) Homepage
    On one of the last projects I worked on, the specs we received from the customer were horrendous. Actually, it wasn't the customer themselves who had done the specs, but another contracting firm. Spending 5 months on the project, and finding repeated errors in the "data maps" (it was apparently too bloody difficult for us to be supplied with a schema for the DBs we were supposed to be accessing and updating), I'd finally had enough.

    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.
  • code comments (Score:2, Insightful)

    by VonKruel ( 40638 ) on Monday May 20, 2002 @05:00AM (#3548944)

    If the code is well structured, variables, classes, methods, etc. well-named and well-conceived, it will explain itself to a large degree, and won't require an English play-by-play of every friggin detail. Generally, it's a good idea to have high-level comments that say "this chunk of code does X", but lower-level comments are often a waste of time, and only serve to clutter the code. Having said that, sometimes code is unavoidably hairy, and you have to recognize cases where the code needs some lower-level explanation, and provide it. First, avoid complexity, failing that, manage it. Generally speaking, I think code comments serve the purpose of helping s/w people to develop a mental map of the code. Code should have as few comments as possible, but no fewer :-)

  • by ralphbecket ( 225429 ) on Monday May 20, 2002 @05:13AM (#3548976)
    Such words of wisdom as I've been able to muster in two decades of experience:

    Comments are vital, but like all programming tools require judicious use to be effective.

    It is easy for large comments to fall out of sync. with the code, so large comments should generally be reserved for high-level documentation of the kind one would expect to find in a literate program. Prefer a pointer (say, a URL) to a document explaining an algorithm than a block of text explaining the algorithm.

    Brief comments on types and data constructors are vital where their use is not obvious. The same goes for functions, methods and procedures.

    Function bodies should be small: it is better to have several small, easily understood functions (with names that clearly convey what they do) than one large block of code.

    Use of formal language in comments keeps them short and clear. Compare the following:
    • take(N, Xs) is the first min(N, length(Xs)) members of the list Xs;

    • take(N, Xs) returns the first N members of the list Xs or the entire list if there are fewer than N members of Xs.


    The term 'list' can be omitted if the function has an explicit type signature (even if your language is untyped, specifying types somewhere is invaluable documentation.) Another point to note is that these comments make clear what happens when N > length(Xs) - you should specify what happens in all circumstances, even if that just means saying "if these conditions are not met then the behaviour is unspecified."

    Including sanity checks in code is a useful alternative to documentation.

    It is a very good idea to annotate code with the invariants that should obtain at key points.

    Eschew clever code. Nobody will be impressed and it's a maintenance nightmare. And you'd better be very sure you got it right...

    Don't cut corners. Include *all* the error checks. Learning how to write elegant robust code is what distinguishes real programmers from cowboys. Managing both is an acquired skill.

    Avoid globals. Seriously.

    State and mutable update lead to unreusability, bugs, madness and divorce. Learn a functional programming language (add smiley if that helps).

    Someone once said words to the effect that if you find yourself writing a bulky comment, ask yourself if you could restructure your code so as to make the comment unnecessary.

    - Ralph
  • by emag ( 4640 ) <<gro.iksrug> <ta> <todhsals>> on Monday May 20, 2002 @05:14AM (#3548979) Homepage
    Oh, you've really touched on a sore spot. At a company I worked for once, there was a group of managers and developers who were working on coding standards for the entire division. Somehow, since *my* manager knew I was a fairly proficient coder, and wanted to make sure our group had input, I ended up on the panel. I remember telling a manager for another project point blank that he was an idiot for insisting that:

    char* foo, bar;

    was good coding practice, while

    char *foo, bar;

    wasn't, because the code was declaring two pointers, and so the * should be with the type and not the variable name.

    Even pulling out K&R, and writing sample code showing the sizeof(foo); vs the sizeof(bar); wouldn't convince him that he was wrong.

    Unfortunately, I don't think it was ever "officially" settled. Nor were several of the other corrections that I immediately made to his "proposed" coding standards document he handed out at the first meeting.

    Thankfully, my manager at the time listened to me (and also, helpfully, knew C and C++), so when we got the coding standards, they were filed with the rest of the useless paperwork we got, and we kept on writing things properly, including:
    • comment blocks before each function describing usage, parameters, expected range of return values, and error conditions
    • comments describing thee amount and type of testing done to verify things worked
    • comments about who had done what with what code and when
    • comments preceeding anything non-obvious about the code itself


    Three guesses as to which project was ahead of schedule. (Of course, not entirely fair, since we also didn't force code generation via Rational Rose. We instead reverse-engineered all of our final UML from the code we'd written and tested, and knew worked the way it was supposed to...)
  • by caveman ( 7893 ) on Monday May 20, 2002 @05:17AM (#3548983)
    I work in a coding shop where our company coding standard insists on some microsoft plot called 'Hungarian Notation'.

    For the unitiated, this means that all variable names have to be prefixed with letters that indicate it's type. i for int, f for float, ch for char, etc.

    The linux CodingStyle file (in the Documentation directory in every kernel source kit since who knows when) slates hungarian notation thus:
    Encoding the type of a function into the name (so-called Hungarian notation) is brain damaged - the compiler knows the types anyway and can check those, and it only confuses the programmer. No wonder MicroSoft makes buggy programs.

    If you don't have Linux kernel sources on your machine, you can get a copy of CodingStyle here [linuxhq.com] (from the 2.0 kernels).

    As a result of all this mucking about, because I tend to look after most of the dynamic memory, linked lists, and low level bit and byte-bashing operations, I end up with variable names with more prefix letters than letters in the name. I really detest this coding standard (which for some reason also forbids the underscore character on the grounds that it looks like a minus. Do you get foo_bar and foo - bar confused? I don't.

    I don't agree with all parts of the Linux CodingStyle, especially the bit about brace placement, but it's a good starting point for any C coding standard. Unfortunately, ours was designed by microsoft-centric folk who think that // is the start of a comment.

    Ayhow, back to topic, the Linux CodingStyle also contains the distilled wisdom:

    Comments are good, but there is also a danger of over-commenting. NEVER try to explain HOW your code works in a comment: it's much better to write the code so that the _working_ is obvious, and it's a waste of time to explain badly written code.
  • by g4dget ( 579145 ) on Monday May 20, 2002 @05:43AM (#3549042)
    Code Complete and similar books strikes me as being a bit like books on nutrition and dieting: they tell you what is good for you and they give you some tips on dieting. But most people who read them end up eating junk food anyway because they just don't have the time to do it right.

    By all means, read Code Complete--its suggestions are sensible. But the real culprit when it comes to poor software are time and resource pressures, feature creep, and other environmental factors. Maybe at least the book will let you recognize when your project is doomed and leave; McConnell seems to have done that--he isn't at Microsoft anymore.

  • by PinglePongle ( 8734 ) on Monday May 20, 2002 @06:05AM (#3549084) Homepage
    In any development effort involving more than 1 person, comments are not enough.

    You should seriously consider :
    • coding standards outlining naming conventions, indentation, common usage, commenting requirements etc.
    • design and code reviews of all non-trivial work products
    • documentation standards (see the book review on agile modelling) - you should document the stuff that isn't obvious, and keep the documents up to date
    • automated unit tests which allow any changes to the code to be tested (yes, I stole that one from the eXtreme Programming guys).


    The problem with comments is that they explain what the code does, but all too often the "why" - the structure of the program - is not obvious by looking at the comments - it's like trying to work out a streetmap by looking at the names in the phonebook.

    I took over a large project from a major consulting firm; much of the code was immaculately commented, but the overall structure of the design was almost impossible to fathom; the documentation was out of date and incomplete, and everybody had a slightly different view of how things worked. Whenever we fixed a bug or made a trivial change, we'd hold our breath just in case the trivial change had unforeseen consequences somewhere else in the system. A simple class diagram and database schema would have been more useful than most of the comments. Unit tests would have saved us literally hundreds of hours of pain...

    Code Complete, a book by Steve McConnell is a great read on this subject; I also recommend "Agile Development" by Cockburn.
  • WHY not WHAT (Score:2, Insightful)

    by mikehunt ( 225807 ) on Monday May 20, 2002 @06:11AM (#3549095)
    Certainly the most important comments are those that say WHY something
    is being done rather than WHAT is being done.

    If the code is written clearly, in sensible size functions and with
    meaninful variable and function names it is easy to see what is happening.
    It's the WHY that often escapes even the original author some
    years down the line.
  • Re:Code Complete (Score:2, Insightful)

    by Anonymous Coward on Monday May 20, 2002 @06:25AM (#3549117)
    One of the most useful things he explains when it comes to comments is that, if you choose your function and variables names well, you shouldn't need many comments.

    e.g.

    // check to see if whatever is true

    if ( [complex bit of code] ) {
    do something;
    }

    This is much better written like this, without the comment:

    Whatever = [complex bit of code];

    if ( Whatever ) {
    do something;
    }

    He gives lots of examples like this, showing how to write your code so it doesn't need so many comments.

    Great book.

  • by Rogerborg ( 306625 ) on Monday May 20, 2002 @06:33AM (#3549127) Homepage
    • All modern compilers that I know of can handle symbol names of at least 256 characters, not the old 31 character limit.
    • The most widely understood naming convention is the English language.
    • If you feel that you have to comment the purpose of a method, function or variable when you declare/define it, why isn't it necessary to comment every use of it as well?
    • The time spend typing or reading characters of code is insignificant compared to the time spent comprehending it.
    • Whenever you write code that requires any interpretation at all, you cost yourself developer time, and that's a precious resource.
    • If you comment something that the language supports, you're not using the language.
    • People who slate you for using over-verbose naming are really saying "You shouldn't need long names to understand my code." That's a solipsistic ego trip, as the target audience isn't or your peers or anyone in a code review or with white box knowledge of the code or system. It's the poor contractor shmuck five, ten or fifteen years down the line who has to come to your code stone cold on to fix a critical bug with a deadline breathing down his neck and a hankering to get the hell out of the office and have some semblance of a life. Write for the benefit of that guy, because one day you'll probably become him.
    • Every time you write a comment, you introduce a potential headache for the maintainers. Ask yourself when the last time you updated a comment in production was, even when it contradicted the code.

    Here's the rules I use:

    • A function/method name is too long when it doesn't fit on a typical screen. 80 characters is about my limit.
    • If I find myself thinking that I'd better comment the purpose of a variable, I incorporate the comment in the variable name. As a side effect, that also tends to give a good feel for how important a variable is.
    • Yes, we all know that "i" is a counter, but what is it counting? It costs me perhaps five seconds to use a variable that describes what is being counted. Then it costs a reader an extra tenth of a second to read it, but that saves a quarter of a second to translate to what it actually means. Let people read your code, don't keep making them stutter and recap.
    • Describing the function and purpose of "input" and "output" parameters in a function description comment is a hell of a long winded way of typing "const WhatTheParameterIsActuallyUsedFor". You only have to type it once; that's what copy and paste is for. Don't comment expected values, assert(them).
    • Completely self commenting code is an unrealistic ideal. But get as close to that ideal as possible, and don't be afraid to change comments when you change the code during maintenance. If you're sure what the code deos, you should have no problems doing that. If you're not sure what the code does, then find out.
  • Re:Code Complete (Score:1, Insightful)

    by Anonymous Coward on Monday May 20, 2002 @06:51AM (#3549151)
    Good, zealots like you don't deserve quality books like this one anyway.
  • by JKR ( 198165 ) on Monday May 20, 2002 @06:51AM (#3549153)
    Hungarian notation is a bit more involved that that, and is actually extremely useful when not taken to extremes. That bit of kernel documentation is opinion, not some God-given truth handed down from the prophets to the great unwashed.

    For example, Hungarian can encompass scope in the variable name, which makes (a small number of) file & project scope globals just about bearable.

    The real win is that it makes pointers obvious - and in a language that encourages pointer arithmetic, that's invaluable for easy reading of code.

    I've used a variant of Hungarian for Java, that uses "m" for member, "a" for function parameter, "s" for class static. It works pretty well, too.

    Try it, you might like it. It's all about personal preference, and I find Hungarian-style prefixs plus InterCapitalisation more readable than some all_lower_case alternative.

    Oh, and "//" is a valid single line comment in ISO C '99. HTH. HAND.

    Jon.

  • My preferences (Score:2, Insightful)

    by Piquan ( 49943 ) on Monday May 20, 2002 @06:55AM (#3549158)

    First off: never underestimate the value of putting research notes in your comments! A simple "This averages O(NlogN), but is worse if the data is presorted" can really make somebody's day.

    Now, the long rambling description of how I like to see comments:

    Every file should have, right after the boilerplate (after copyright, before #includes etc) a brief description of that file.

    ;;; This implements the SAMHAIN algorithm for performing
    ;;; constraint propogation. The caller passes a list of nodes...
    ;;; [Description of what SAMHAIN does ommitted for brevity on /.]
    ;;;
    ;;; The algorithm here is loosely based on the one in "Paradigms of
    ;;; Artificial Intelligence Programming", chapter 17. There, it was
    ;;; used as part of a vision algorithm, but it's still labelling a
    ;;; graph by constraint propogation.

    Name your functions something concise, and accurate, but not necessarily precise. You don't need sort-sequence-on-predicate when sort will do just as nicely.

    The same goes for variables. Using i and j for numeric iterators is fine, but you rarely should use foo and bar. Most variables should also have a short (usually <20 char) comment, although globals should have a longer comment, possibly describing how they're used.

    Every function should have a docstring. In some languages, such as C, this is normally comments at the beginning of the function. In some, such as Lisp, there are conventions for including the docstring in a manner that the compiler will recognize.

    The first line of the docstring should be a self-contained sentence that tells what the function does. The rest can go into detail about how to call it. The purpose of this bit is "what does a caller of this function need to know". Wait on the implementation notes for now... we want the caller information to be all one, tidy package.

    (defun sort (predicate sequence)
    "Destructively sort SEQUENCE.
    Predicate should be a function of two arguments, and should return T if its first argument should precede the second."

    If your language does have docstring support (either directly or through an external tool), then implementation notes belong in comments, not the docstring. Either way, put them after the caller information, so that somebody who just wants to use your function doesn't need to read them.

    (defun sort (predicate sequence)
    "Destructively sort SEQUENCE.
    Predicate should be a function of two arguments, and should return T if its first argument should precede the second."
    ;; We use a modified partition-exchange sort.
    ;; See also Hoare, C.A.R., "Quicksort", The Computer Journal, 5:1, pp. 10-15, 1962.

    As an extention of this idea, functions should begin with a brief overview of how they work. (For extremely simple functions, this may be omitted.) If the function implements a formal algorithm, such as a sort or hash algorithm, then a formal description is certainly not out of place, or give a reference. This is also a good place to note any behavorial characteristics.

    ;; See also Hoare, C.A.R., "Quicksort", The Computer Journal, 5:1, pp. 10-15, 1962,
    ;; and Knuth, D.E., "Sorting and Searching", The Art of Computer Programming,
    ;; Vol. 3, pp. 114-123, 145-149, 1968, particularly algorithm Q.
    ;;
    ;; Takes O N lg N average time. This implementation uses median
    ;; selection to avoid its O N**2 worst-case behavior.
    ;;
    ;; If the data has a pre-existing order, use mergesort instead.

    Divide your code into "paragraphs", between 5 and 20 lines long. Skip a blank line between paragraphs. This also helps find areas that are good candidates for factoring out into separate functions.

    Each paragraph may start with a block comment describing either what that paragraph does, or at least the program's state at that point in execution. Feel free to make these as descriptive as you like; they're the landmarks for somebody reading the code.

    ;; If the inner loop only executed once, then there were only enough
    ;; elements for two subsequences given n, so all the elements have
    ;; been merged into one list. Start-1 will have remained 0 upon exit.

    Loop guards frequently should have a one-line comment describing what they're testing for, in terms of the algorithm as a whole.

    (when (< ,end-1 ,vector-len) ; there are enough elements for a second run

    If a line's meaning isn't immediately clear, then clarify it with a one-liner.

    (let* ((retval-cons (cons :placeholder list)) ;:placeholder will be deleted later

    Any one-liners may be expanded to multi-liners if you need to:

    /* log_forward ignores SIGCHLD, so we must reset it to catch the
    * sendmail exit status. */
    signal (SIGCHLD, SIG_DFL);

    Mark areas that need investigation or more work with a comment of "FIXME"; that makes grepping later on much easier.

    res = pthread_mutex_unlock(&msg_thread->mutex);
    / * FIXME The error handling here needs to be more robust. */
    if (res != 0)
    d_errc(EX_OSERR, res, "cannot release worker thread");

    You can also use XXX for a similar purpose, or (what I do) to mark areas of grave significance.

    /* Frees all transitions out of a state. XXX Whatever calls this must
    * either reinitialize the transitions slist or free the structure. */
    static void
    free_transitions(struct matcher_u *matcher)

    Don't worry about descriptive comments being too verbose. Descriptions of program state, why something exists, research notes, or prose all have their place in comments. The only time I've read a file and thought "Gee, this is overcommented" was when it had template comments with changelogs and argument lists.

    Now what do you not use comments for?

    Don't keep a changelog in your code. Your source-control system does a much better job.

    Don't repeat the argument list. The argument list itself does a perfectly fine job of that, and will always be up-to-date. If the purpose of each argument isn't clear by its name, then add a one-line comment to the arguments. (Note: In Perl, don't shift the arguments off as needed. Get all the arguments off in the first line of code if possible, such as my ($self,$filename,$options) = @_; in order to let somebody calling the function to have an argument list available!)

    Don't document the language (eg, explaining ++). This not only is unhelpful, but distracts from useful comments. If somebody doesn't know what ++ does, they can look it up.

    Credits: Examples snipped and adapted from my own development, as well as CMUCL and FreeBSD sources.

  • by Anonymous Coward on Monday May 20, 2002 @07:19AM (#3549201)
    While you're true, somehow you are true "after the fact". What I mean is you can always find a programmer telling you that his code is a big mass of underdocumented shit not because his will but because time constrains and feature shifting from his boss/client.

    And they are usually rigth, *BUT* to-date I *NEVER* haven't seen the situation of a programmer being fired when it is obvious that he *is* productive *and* he has done his best and even then it has been imposible to achieve a goal (because stupid asumptions/time lines from management). This being said there *is* a real problem from the fact that programmers like the *most* programming, that is, writting down lines of code, not documenting, not commenting, not designing prior to code, no nothing but code. Under these circumnstances, when time forces them to cut down something they end up cutting down from the comments/desing side, *not* from the coding one.
    Now the difference results on...

    Case A (usual case)
    for(foo=0;foo=7;++foo)
    {
    bar=foo*2; pee=bar/3;
    }
    -BEEEEP TIME-LINE REACHED. IT'S THE WORK DONE?
    -Yes boss, it is.

    Case B (good way)
    /* Testing if current they of the week is workable, so subrutine playable_day is aplicable */
    for(weekday=SUNDAY;weekday=SATURDAY; ++weekday)
    {
    }
    -BEEEEP TIME-LINE REACHED. IT'S THE WORK DONE?
    -No boss, it isn't. Look at my code, I worked as much sensible code lines as anyone else but has been *IMPOSSIBLE* to finish. I told you this needed two days, not only one.
    -OK: if it *REALLY* can't be done, it can't be done. Continue, please.

    What I mean is that programmers themselves are as guilty as management because when management forces a stupid time-line, they stupidly do the wrong things so work seems to be rigthly done (like avoiding coding conventions, documenting and the like). If what can't be rigthly done is not done at all even management will make better asumptions next time.

    So:
    1/ Sensible variable-names; use name-sensible constant as much as you can too;
    2/ *What* the code does can be understood from the code itself; comments should focus on *why* (there are exceptions, of course... Perl's regular expresions are a good place about commenting not only why, but how too).
    3/ If at all possible COMMENT FIRST, THEN CODE. DON'T LEAVE COMMENTS TO THE END, or you will never write them down.
    4/ If at all possible use any autodocumenting tool (javadoc, doxygen, etc.) while they still need some discipline from your side it's usually far (psicologically) easier to maintain documentation up-to-date with them than if you're expected to go to an outlined document and do it.

    Well, my two cents.
  • by Bob9113 ( 14996 ) on Monday May 20, 2002 @07:36AM (#3549258) Homepage
    In any situation where I see the need for code commentary, I try first to find a way to make the code clearer. If the source code is sufficiently clear, comments are unnecessary. This also avoids the risk that the comments will diverge from the code - making claims that were once true, but no longer reflect the code's actual logic.

    This is poorly commented code (despite the fact that the comment is clear and accurate):

    aClassName = aTask.getUiInitializerClassName();
    // empty or null uiInitializerClassName means this task is not
    // defined for use in this interface. Skip it.
    if( aClassName != null && ! aClassName.equals( "" ) ) {
    ... do something ...
    }


    This is well commented code (despite the fact that there are no comments at all):

    initializerName = aTask.getUiInitializerClassName();
    boolean isNotNull = initializerName != null;
    boolean isNotEmpty = ! initializerName.equals( "" );
    boolean definedForThisUi = isNotNull && isNotEmpty;
    if( definedForThisUi ) {
    ... do something ...
    }

    Of course, this doesn't work in all situations, but I find that I can improve the clarity and accuracy of seventy to eighty percent of my commentary this way.
  • Re:Good Comments (Score:4, Insightful)

    by Cederic ( 9623 ) on Monday May 20, 2002 @08:05AM (#3549361) Journal

    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
  • by Cederic ( 9623 ) on Monday May 20, 2002 @08:15AM (#3549399) Journal

    Yes, we can tell it's been quite a while.

    Right now, businesses go to their IT teams and say "We need software that does X. Deliver it in 8 weeks."

    It would take 8 weeks to write a structure document in the manner you are describing (especially going through the various top-down iterations to reach code).

    Instead we have to write the basic framework of the solution, get that ready in four weeks, and then change and tweak all the little pieces of functionality that have changed in the requirements since we started. Because businesses don't know what they want, and all that is definite is the go live date (usually because the Marketing team have a fixed launch date)

    How are you meant to pre-document a requirement that arrives three days before go-live? With a suitable methodology you can add it, test it, and regression test the rest of the system to be sure you haven't broken it. But then generating user documentation too? Dream on, that's going to have to wait.

    ~Cederic
  • by Anonymous Brave Guy ( 457657 ) on Monday May 20, 2002 @08:22AM (#3549425)
    Actually, if your variables and functions names are meaningful you DON't NEED Comments.

    Sorry, but that's just not true.

    You need fewer comments if your identifiers are well-chosen, certainly. But I've never seen a significant piece of code that would be adequately described by well-chosen identifiers alone.

  • Re:Good Comments (Score:5, Insightful)

    by MadAndy ( 122592 ) on Monday May 20, 2002 @08:33AM (#3549495)
    Changes have to be done twice? That's right, when they change the code, they must change the comment.

    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)

    by Simon Brooke ( 45012 ) <stillyet@googlemail.com> on Monday May 20, 2002 @08:53AM (#3549605) Homepage Journal
    Every time someone has to change some code, you've just forced them to double their workload, and change some comments too... Inline comments are a major headache - they're painful to write, painful to maintain, and dangerous if they aren't maintained.

    ... 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.

  • Golden Rule (Score:3, Insightful)

    by Salamander ( 33735 ) <jeffNO@SPAMpl.atyp.us> on Monday May 20, 2002 @09:02AM (#3549648) Homepage Journal

    The most important thing wrt to commenting code is to put yourself in the reader's shoes. What would that reader need to know that's not obvious from the code? One useful exercise is to pretend that you're leaving your job and you're doing a brain-dump for the (reasonably bright) person who will inherit your code. Your goal is to anticipate every question they ask or suggestion they make, in the form of a comment. If they're likely to ask what something does or how it works, add a comment. If you add code to fix a specific bug then add a comment; obviously you didn't recognize the need for that code at first, or else there wouldn't have been a bug, so the next person probably won't either unless you comment it. If they're likely to say "this would be better if xxx" but you already tried xxx, put in a comment that says "we already tried xxx but it didn't work because..." IMO that last is the single most useful kind of comment because it saves someone from going down a blind alley. BTW, the same "role-playing" approach works really well for specs too.

    Another important skill is knowing when not to comment something. If it's blazingly obvious what something does and how/why it does it, don't comment it. If there are too many comments, the person reading the code will often decide that reading the comments is a waste of their time and they'll just start ignoring them. Then they'll miss the one comment that really does matter. If you must be verbose in your commenting, at least use some sort of visually obvious marker for really important "you'll break it if you ignore this" kinds of comments, to distinguish them from the less important stuff.

    Lastly, don't be afraid to spice up your comments. Be totally candid about stuff - yours or someone else's - that you think is brain-dead. Make wisecracks and in-jokes, within the bounds of good taste and brevity. People are more likely to read your comments if they can occasionally get a chuckle out of them. They're more likely to enjoy working on your code, and speak well of it/you when asked. These are all good things - for you, for them, for your employer or client. Coding can be dreary enough without robotic comments.

  • by Anonymous Coward on Monday May 20, 2002 @09:07AM (#3549687)
    I learned to comment the end of if structures and function blocks to make the code easier to follow... just add " } //end if" or something.

    Yuck. I had to take some code over from someone who did that. It might be appropriate for your system, but it was the silliest thing I ever saw. It would have been better if the code I saw had kept the braces lined up. The original code had braces all over the place, and //end if statements to try to fix the problem

    void myRoutine(void) {
    ...
    if (idx == 5)
    {
    ...

    } //end if
    }

    With properly aligned braces, putting //end if just clutters it up.

  • by Anonymous Coward on Monday May 20, 2002 @09:14AM (#3549743)
    "I learned to comment the end of if structures and function blocks to make the code easier to follow... just add " } //end if" or something."

    I agree with most of your comments (pun intended). The above quoted text is the only place in which I strongly disagree. The world of source code would be a vastly better place if people would simply drop the K
    do yet more code;
    }
    }

    There is no need for commenting the ending brace in this style since it is much easier to see where the braces match up. It's also cleaner and much better looking than:

    if (someCondition) {
    while (someCondition) {{
    do more code;
    do yet more code;
    }
    }

    The K&R style requires significantly more effort to unmangle, even when there are only a couple levels of indentation. For example, how many of you caught that double opening brace? No doubt several of you caught of, and no doubt several of you had to go back at least once to find it. Now imagine having to do that for a much longer piece of code.

    Of course, lining up your braces is not a cure for inattention, but it greatly increases your chances of picking up such a common syntax error. It's also incalculably easier for new programmers to read.
  • by tslarkin ( 580420 ) on Monday May 20, 2002 @09:44AM (#3550016)
    Literate programming is to comments what a high level language like Pascal is to assembly language.

    Programmers have the weakness of thinking that they are writing for a compiler. They should be imagining that they are writing for another human reader. This is the essence of literate programming, which is, in my opinion, the only good idea that anyone has ever had about program documentation.

    If the programmer is restricted to interspersing comment lines between lines of code, then the elaboration of the documentation must follow the sequence of the code. To use a simple example, if I write a class definition, then I must declare all the member variables within the block of text that begins "class foo" and ends with "};". However, that may not be the best way to explain the significance of those variables. Maybe it would make more sense (for the human reader) to delay the declaration of a member variable until the place where it is first used. This can easily be done with CWeb. This simple example is hardly sufficient to reveal the power of LP. It is well worth taking a serious look.

    After the literate program is written, it is processed by two other programs. One produces a file suitable for submission to a compiler. The other produces a TeX file, which outputs a properly formatter version to be read by a human.

    The code itself is never the best documentation. It's not documentation at all, except in the most trivial cases.

    Any programmer can write a literate program. It's just a matter of understanding who his audience is.
  • Re:Variable Names (Score:3, Insightful)

    by jeremyp ( 130771 ) on Monday May 20, 2002 @10:01AM (#3550146) Homepage Journal
    There's a third thing the maintainer needs to know which is "what it's *supposed* to do. Comments are invaluable for that. Consider the following C code fragment:

    for (i = 1 ; i ARRAY_SIZE ; ++i)
    {
    do_something_to (array [i]) ;
    }

    Why isn't it doing something with element 0?
    Now look at these two fragments

    /* Do something to all elements in array */

    for (i = 1 ; i ARRAY_SIZE ; ++i)
    {
    do_something_to (array [i]) ;
    }

    and

    /* Do something to all elements in array except */
    /* the first one because... */

    for (i = 1 ; i ARRAY_SIZE ; ++i)
    {
    do_something_to (array [i]) ;
    }

    Just by adding a one line comment, a bug has been exposed, or the maintainer has been prevented from inserting a bug in the second instance.

    As a maintainer, I'd want to be able to see what the code does (well set out, good structure, descriptive names etc) and what the programmer meant it to do, i.e. good comments.

    Anybody who puts jokey unhelpful comments in their code should be aware that these will inspire feelings of hatred and extreme violence towards them in the maintainer who has two hours to fixe the air traffic control system before the 747s start falling out of the sky.
  • by goodviking ( 71533 ) on Monday May 20, 2002 @11:20AM (#3550810) Journal
    Some variation of the methods described in "Literate Programming" [stanford.edu] by Donald Knuth [stanford.edu] are a good place to start. In summary, Knuth says that you should be able to extract from the same source both machine instructions, and a human parsable document, with unusually high importance placed on the later. Whether or not you want to imbed LaTeX [latex-project.org] into your document is up to you (I never have bothered), but on the whole find something that will make your code and algorithms understandable to another programmer who's never met you (because that's probably who will be either grading or maintaining your code at some point).
  • by Mr. Fred Smoothie ( 302446 ) on Monday May 20, 2002 @11:32AM (#3550909)
    One of the great insights of the Agile Software Development movement, if you ask me, is the realization that a process which doesn't take into account the strengths and weaknesses of the people who will use it is flawed.

    So, it's one thing to say "if they change the code, they MUST change the comments", but realize that unless you have the ability to force the issue (a tool to make you change comments before saving changes, managers who care more about firing programmers who don't follow code standards than avoiding schedule slippage -- hint: I've never seen one of these, EVER), 9 times out of 10, they just won't do it. It's like teaching abstinance as a method of reducing teen pregnancy.

    Thus, the practice of having comments which are redundant w/ the code is simply setting the project up for failure as the parent poster pointed out.

  • by Mr. Fred Smoothie ( 302446 ) on Monday May 20, 2002 @11:45AM (#3551023)
    So what happens when the code changes and breaks the assumptions so fastidiously outlined in the documentation?

    It's less of an issue w/ Javadoc and Doxygen comments (which is embedded in the code) than external documentation, but the fact is that managers reward code changes, not documentation changes, and programmers are lazy.

    Until you can change these basic, simple facts, what are you going to do? One strategy is to encourage self-documenting coding standards as well as encourage documentation updates. But people NEED to remain aware of the basic principle that the only authoritative documentation is the source code itself.

  • Re:Good Comments (Score:3, Insightful)

    by ClarkEvans ( 102211 ) on Monday May 20, 2002 @12:48PM (#3551506) Homepage
    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.

    The comments should talk about _what_ the module dues, not _how_ it does it. Stick with this distinction and it'll be a bit easier. If your module changes so much that the _what_ changes... then you really should take the time to reconsider your comments... as they may point out what assumptions other code may be making and where compensating changes may be needed.
  • by Anonymous Coward on Monday May 20, 2002 @01:06PM (#3551678)
    The whole point is that you don't have to keep scrolling around. You see the call to getSubtotal() and you know it just adds up all the numbers without having to see the code.
  • by feloneous cat ( 564318 ) on Monday May 20, 2002 @01:52PM (#3552046)
    My favorite "useless" comment was one that was part of a (thank gawd) proprietary OS which had in the header to a chunk of assembly language "DOES NOT CHANGE REGISTER HL". The first thing it did was change register HL.

    My point is that comments can be as much a problem as they can be a solution. If you have time to change the code, but no time to change the comment, then in essence you may as well have NO COMMENTS. Which really defeats the purpose.

    I have found, for the most part, that GOOD function and variable names are FAR better than a half page of comments (as an example, take a page of C++ code and change all the variables to one character... see how hard that is to read?).

    Second, ignore the law that says we can't exceed 80 columns. It is dumb. It is old. It defeats the purpose of having a HUGE SCREEN with little teeny lines. 80 columns are the size of IBM punch cards. AKA dinosaurs.

    Third, kill whomever sez that Hungarian notation helps. It doesn't. It is the SECOND DUMBEST thing to come out of Microsoft. People who adopt it are mindless beasts of burden. You don't want to be one of THEM do you?

    Fourth, BE FANATICAL about taking the what reads from others and discard what doesn't. I used to make boxes with slashes and dashes, etc. When I realized I spent more time "refixing boxes" I got rid of the boxes.

    Fifth, is the best size for a bottle of gin. Gin and tonics may not help with coding, but they take the pain away from reading others code. Also good when the boss says "so, what the hell does this mean?".

    Sixth, "standards" doesn't mean squat in the real world. Getting code out is far more important. Learn what is absolutely required for comments.

    Seventh, if it is a trick TELL THE READER! Your audience is the next guy who has to support your dreck...er...wonderful creation. He is probably going to be less brilliant. If you use a trick of the compiler, LET HIM KNOW. I have worked (and written) code that dies a mysterious death when you "optimize it" - when in fact it IS optimized.

    Eighth, learn from the screwups of others. If something you picked up reads like crap, then figure out how to make it better. Does it need to be indented more? Better variable names? Etc. Surprisingly, others probably had the same problem.

    Ninth, NEVER write code with comments like "YES". I knew of a HUGE chunk (when printed is stood three feet tall) which had five comments in it. One was "YES". The contractor had to sit for several days with it remembering what it did before he could modify it. Mindblowing, isn't it?

    Tenth, Keep evolving. Writing comments is a lot like writing code, you get better at it as you get older. And the style eventually gets more terse, but more reasonable. Eleventh, EVEN if it seems obvious, sometimes it may not be. Be prepared to defend what may seem like simplistic comments. Twelfth, This is the most important. BE CONSISTANT.
  • by vanyel ( 28049 ) on Monday May 20, 2002 @02:49PM (#3552537) Journal
    Unfortunately, this is rarely practical, but I find the most useful comments are written when I'm going back through code I wrote over a week ago. The reasons for doing things are no longer on the surface, and thus if there's something I look at and have to dig for understanding, then it needs better explanation.
  • Functions should have their arguments documented-- what they mean and what they do, and their return values documented. That is sufficient.

    Inline comments have a place, but they are way over used. If you are telling me how your program works using inline comments, I will ignore those comments becuase if there is a problem, your code may not behave as advertized.

    Instead inline comments should document WHY you do something a certain way and help me to understand what problems caused a particular piece of code to us a particularly clumsy algorythm or why a seeminly extranious bit of code was added. Don't tell me how-- that is what the code is for.

    And use whitespace as your friend to break things up into logical chunks which are easily readable and logically connected. This is the reason for indenting your code, but the same principle can be used by adding additional line breaks to separate logical chunks of code (this makes more sense then meaninglessly breaking up functions).

    I think that these are relatively language independent advice. I use it in Perl and PHP, and when I read C and C++, I appreciate these tips as well.
  • by Anonymous Coward on Tuesday May 21, 2002 @05:15PM (#3561405)
    I have only one thing to say:

    GUARD CLAUSES.

    void doWork(String initializerName) {
    if (initializerName == null)
    return;
    if (initializerName.equals(""))
    return;

    ... do something ...

    };

    *THAT* is well commented code, with no comments. What you had was a namespace-eating, inefficient scope nightmare :) no offense.

    Functions. Lots of functions. Whenever you find yourself tempted to add variables for a single use, you are missing a function with guard clauses.

    (In case you didn't guess, a guard class is a boolean test with return at the start of a function, basically a drop-out test. They're nice and sequential, remove the need for large amounts of indentation in nested if's, and are terribly easy to read.)

This process can check if this value is zero, and if it is, it does something child-like. -- Forbes Burkowski, CS 454, University of Washington

Working...