Slashdot Mirror


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

275 of 802 comments (clear)

  1. Code Complete by kimba · · Score: 5, Informative

    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.

    1. Re:Code Complete by NewtonsLaw · · Score: 5, Insightful

      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?

    2. Re:Code Complete by ZanshinWedge · · Score: 2

      I agree completely, it should be on every programmer's bookshelf. You can hardly call yourself a professional software engineer if you have not read this book.

    3. Re:Code Complete by jsse · · Score: 3, Funny

      Yes, it is published by Microsoft

      *Abruptly stops the finger from clicking the link*

    4. Re:Code Complete by Anonymous Coward · · Score: 2, Insightful

      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.

    5. Re:Code Complete by Anonymous Coward · · Score: 2, Funny

      They must have read it in the process of writing it; so they were not professionals before, but they were after. But my opinion doesn't count for much -- I haven't read it -- I can hardly call myself a professional software engineer.

    6. Re:Code Complete by arkanes · · Score: 2

      Microsoft Press also publishes a magnificent book called "Writing Secure Code". Interestingly, the guys who write it (MS engineers) talk alot about how hard it is to force secure coding onto co-workers who don't give a shit.

    7. Re:Code Complete by SecurityGuy · · Score: 2

      Steve McConnell doesn't work for Microsoft. He's worked for them in a contracting role, and has also written a highly insightful piece which explains a heck of a lot about why Microsoft is so hopeless, although he may not have intended it to carry that meaning. Basically, a high premium is placed on making the developer happy. Creeping featurism isn't seen as a problem. Of course you can figure this out by using any of their products as well.

    8. Re:Code Complete by juliao · · Score: 2
      From the people who gave us Hungarian notation?

      Learning coding styles from Microsoft is like getting cooking tips from McDonalds...

    9. Re:Code Complete by Ooblek · · Score: 2

      Comments in code? The poster must not be a Jedi, for real Jedi do not need comments. They can feel the purpose of the code.

    10. Re:Code Complete by Misha · · Score: 2

      Yes it sucks. This is straight from one of many Microsoft's HN intros, which I assume Code Complete also contains.

      In conclusion, the name of our quantity would be coRed, provided that the color type co is properly documented. The value of the name will show later in program segments such as the following:

      if co == coRed then *mpcopx[coRed]+=dx ...



      is that as unreadable to you as it is to me? the only thing i can extract from it is that i should read the documentation for the type co, rather than find out what this line does. sure, my dyslexia is not helping, but they could have done much better.

      yes, outlawing turing machines would be bad, but it's not like you have one sitting on you desk, do you? ; )

      --



      I was thinking of how to intentionally fail my drug test... It would make a good memoir story someday.
    11. Re:Code Complete by sydb · · Score: 2

      Or perhaps "Ethics in Software" by Bill G.

      --
      Yours Sincerely, Michael.
  2. Make the variable names mean something! by dweezle · · Score: 2

    I Have to scan through code regularily and the biggest problem is the variable names. I realize that they must mean something to the coder but to us maintainers they're most times akin to Sanskrit. Function(method) comments are nice too.

    --
    In a time of universal lies, Telling the Truth is a revolutionary act - George Orwell
    1. Re:Make the variable names mean something! by jilles · · Score: 2

      Yes I would have to second that. In addition, it also helps to trust the compiler a bit more to do the inlining. If a method has more than a screen full of code (i.e. about 20 lines), split the method into multiple methods. This has two advantages: you give a name to a piece of related code (abstraction) and you may be able to reuse the function. A good compiler will inline so there's no performance penalty.

      Similarly if your module/class whatever becomes too large it will be more difficult to maintain. Usually large modules/classes are a clear indication of lack of cohesiveness which is bad for maintainability.

      Another thing that can be extremely helpfull are pretty printers (the beautifier that comes with JEdit is great, automatically does its job whenever you save). Good ones also generate the necessary Javadoc stubs (if you're coding Java) thus lowering the burden of creating meaningfull comments (javadoc like tools exist for C++ too!). In addition pretty printers give your code a uniform structure, making it easier to browse.

      Enforcing all this requires code reviews. Most larger software organizations with competent software developers in charge will insist on this already.

      --

      Jilles
    2. Re:Make the variable names mean something! by Mr.+Slippery · · Score: 5, Informative
      If a method has more than a screen full of code (i.e. about 20 lines), split the method into multiple methods

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

      void foo()
      {
      foo_part_1();
      foo_part_2();
      foo_part_3();
      }

      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
    3. Re:Make the variable names mean something! by jilles · · Score: 2

      I've never seen a method over 20 lines that really needed to be that long. Long methods are usually the result of poor design. If you have to maintain such methods, you lose a great deal of time figuring out what they do. Because they are so long, the method name is not a great help in figuring out what it's supposed to do.

      --

      Jilles
    4. Re:Make the variable names mean something! by spudnic · · Score: 2

      From your last couple of comments it seems evident that you need to become acquainted with the use of CTRL-] in vim to do all the jumping around for you. ;)

      .

      --
      load "linux",8,1
    5. Re:Make the variable names mean something! by Fulcrum+of+Evil · · Score: 2

      I've never seen a method over 20 lines that really needed to be that long.

      I've got one right now that's 20 lines, just for the setup and return. The meat should be another 20 lines or so. Of course, this is parsing a free-form text field.

      --
      "We returned the General to El Salvador, or maybe Guatemala, it's difficult to tell from 10,000 feet"
    6. Re:Make the variable names mean something! by SteelX · · Score: 2

      Doesn't that depend on the language being used?

    7. Re:Make the variable names mean something! by ebyrob · · Score: 2

      Having trouble reading your code? It's probably a better idea to break your code up into functions that are likely to be useful in more than one place. Instead of just breaking them up because they are too long.

      If this doesn't seem to work for you, I'd have to see some specific examples...

    8. Re:Make the variable names mean something! by ebyrob · · Score: 2

      I wholeheartedly agree! Having to dredge through a few difficult functions doesn't take that much time. By contrast, trying to figure out what 50,000 functions do in a million line program can drive a developer (or maintainer) insane! Especially if only 10,000 functions do anything useful.

      That said, every rule needs some limits. I've also waded through functions that required 4 source files (due to 32k compiler limits) and been ready to commit great voilence afterwards.

      I find that combining your rule of functions matching abstractions with an effort to reduce total code size works the best for me. My guiding princible is this: "Will the next person to see this line of code, program, etc be glad it exists, or wish it didn't."

  3. Describe before you apply by inflex · · Score: 3, Funny
    I like to see comments where the function of the next code block is well described in a continuous comment block. Additionally, any further specific comments can be placed at the end, or on top of the lines in question. It's simple enough, and permits comment/documenting-scrapers to produce some potentially useful documentation.


    ie,
    // Foo():infinite loop
    // We attempt to complete an infinite loop
    // here as quickly as possible, in order to
    // remain true to Linus's statements of
    // being able to do them faster with linux.
    while (1) {
    ... // Oooh, this is a fancy line, watch out for it doing nothing.
    }

    1. Re:Describe before you apply by ranulf · · Score: 2, Interesting
      The problem with this is that
      while (1) {...}
      or more commonly
      for (;;) {...}
      is a well known construct for infinite loop. If you turn such a simple construct into six lines of source, then I dread to think how much commenting you'll use when you actually get down to solving the problem in hand.

      for (;;) { // infinite loop
      is far better - it reminds people what you're doing and if someone sees your code and doesn't understand that construct then they know what it does from the comment and they can go and find out how it works and learn it for next time.

      While you're at it, you should probably think about hiring real programmers who know basic constructs in their chosen language...

    2. Re:Describe before you apply by spongman · · Score: 3, Interesting
      how about while (true) { ?

      1) It reads right in english.
      2) It's type-safe in C++ for -Wall.
      3) It doesn't use antequated or obfuscated C-isms.

      I can't stand things like:
      #define ever ;;
      ...
      for (ever) {

    3. Re:Describe before you apply by peddrenth · · Score: 2

      while(true) { can be especially useful in an program you're hoping to secure the maintenance contract on...

      ... right after you've redefined true.

    4. Re:Describe before you apply by Permission+Denied · · Score: 2
      #define ever ;;
      ...
      for (ever) {

      This is nasty because the programmer is trying to be cute with the macro. However, if you see this:

      for (;;) {

      And it pisses you off, that means you haven't seen enough of other people's code yet. This is perfectly idiomatic and it reads as "for ever." Don't try to invent new idioms, or apply Pascal and Java idioms to C and C++. If someone prefers "for (;;)" that's purely a stylistic decision, and it's a valid stylistic decision since a lot of C and C++ programmers do that.

      Real code shouldn't look like pseudocode: it should be idiomatic and idiomatic C++ looks nothing like pseudocode. Consider, for instance, looping over an STL collection using an iterator: that looks nothing like pseudocode (where you would just say "for each x in y" or something similar), but it should be perfectly recognizable to any C programmer (eg, you can recognize it as a for-each with a glance, without stopping and thinking - important cognitive distinction).

      Summary:
      C:

      for (;;) {
      or
      while (1) {
      In C++, you can also use:
      while (true) {
      But you should never use "while (true)" in C because a given project might use boolean types defined by six different APIs (all incompatible - so just use an int instead).

      All three of the above are in common use in C++ and getting pissed whenever you see one of them indicates a lack of the "interpersonal skills" managers are always talking about.

  4. Microsoft Press by ObviousGuy · · Score: 2

    Code Complete by Steve McConnell

    Writing Solid Code by Steve Maguire

    --
    I have been pwned because my /. password was too easy to guess.
  5. Per project by mnordstr · · Score: 2, Insightful

    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

    1. Re:Per project by Euphonious+Coward · · Score: 2
      That coding standard has a phenomenal amount of bad advice. Some of it is outdated, some just thoughtless. The omissions are as bad as the mistakes. (Where is exception-handling policy?) It's unfortunate, because there's lots of good advice there too, and an inexperienced programmer can't tell which is which.

      I have my own compendium of significant omissions at http://cantrip.org/coding-standard.html.

  6. Timeless Prof D.Knuth says it best... by gmarceau · · Score: 2, Informative

    The practitioner of literate programming can be regarded as an essayist, whose main concern is with exposition and excellence of style. Such an author, with thesaurus in hand, chooses the names of variables carefully and explains what each variable means. He or she strives for a program that is comprehensible because its concepts have been introduced in an order that is best for human understanding, using a mixture of formal and informal methods that reinforce each other. Donald Knuth. "Literate Programming (1984)" in Literate Programming. CSLI, 1992, pg. 99.

    --
    This post was compiled with `% gec -O`. email me if you need the sources
    1. Re:Timeless Prof D.Knuth says it best... by AYeomans · · Score: 2, Informative
      Check out Knuth's CWEB:


      "CWEB is a version of WEB for documenting C, C++, and Java programs. ... If you are in the software industry and do not use CWEB but your competitors do, your competitors will soon overtake you---and you'll miss out on a lot of fun besides."


      The CWEB page also includes example programs, but you will have to run them through CWEB to get the hyperlinked PDF files.

      --
      Andrew Yeomans
    2. Re:Timeless Prof D.Knuth says it best... by tslarkin · · Score: 3, Insightful

      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.

    3. Re:Timeless Prof D.Knuth says it best... by dvdeug · · Score: 2

      It's interesting that the literate programming tool I'm most familiar with, noweb (because it's not bound to any one programming language, and I don't usually program in C or Pascal), isn't itself a literate program, because a literate program was too much work according to the author. The only major literate programs I'm familiar with are those written by Donald Knuth.

  7. Just tell me what a section of code is for. by foniksonik · · Score: 2

    I only work with Perl. When I'm looking at someone else's code all I ask is that they outline the basic function of a particular section of code so when I need to change/enhance/debug something I can find the right area to start looking as quickly as possible.

    I've never had to deal with 'obfuscated' code so I don't know about onscure variables, etc.. or how much more complicating they could be to my task.

    Just point me in the right direction. Anything else is going to be too much or too little... and if I don't already know what the code is supposed to be doing I probably should be talking to someone who does before I sit down to work on the code itself.

    Obviously reverse engineering of software is a whole different beast.

    --
    A fool throws a stone into a well and a thousand sages can not remove it.
    1. Re:Just tell me what a section of code is for. by inflex · · Score: 2, Funny

      "I've never had to deal with 'obfuscated' code so I don't know about onscure variables, etc"

      I thought Perl was the most efficient self-obfusicating code ever.

  8. Good Comments by jamieo · · Score: 4, Insightful

    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.

    1. Re:Good Comments by Cederic · · 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

    2. Re:Good Comments by MadAndy · · Score: 5, Insightful
      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.

    3. Re:Good Comments by Simon+Brooke · · Score: 4, Insightful
      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.

      --
      I'm old enough to remember when discussions on Slashdot were well informed.
    4. Re:Good Comments by G-funk · · Score: 2

      I'd like to expand on this. A technique I use is this (yes, when I'm being paid I write ASP, when I'm not it's php).

      I start with a function like this

      function checkBarIsFooable(objBar)

      'Check for condition a exit if true
      'Check for condition b exit if true
      'Get response data
      'clean data
      'compare with database
      'fallback if apple = kwyjibo

      end function

      And then once I've got the (almost psuedo code) comments, I flesh it out, but with an extra indentation for code (one more than the comments) so it's easy to skim over the function and see how it does it's thing.

      I try to have a comment every 5 to 15 lines of code. It's especially good when you're writing code to check permissions on certain object user relationships like I have been lately, give it a try - and if you have any better ideas I'm all ears!

      --
      Send lawyers, guns, and money!
    5. Re:Good Comments by jamieo · · Score: 3, Interesting

      I agree with the "increment loop counter" comment, that isn't worthwhile at all - but that's the difference between good and bad comments ;)

      However, I completely disagree with your premise about this being a maintenance nightmare and doubling workload.

      It's the exact opposite of a maintenance nightmare - it helps maintenance (certainly for long running large projects with developer turnover).

      It's also very little overhead. If you are a professional developer, just count how many hours you really write code in a week of working. It's not a great deal really, and the added time to add good comments is very little. The rewards of doing it are far greater than any costs.

      This is a complete mindset thing, just like coding standards - if you get in the mindset, it's easy and no cost, if you moan and complain and fight them all the time it's a pain and loads of work.

    6. Re:Good Comments by ClarkEvans · · Score: 3, 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.

      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.

    7. Re:Good Comments by ebyrob · · Score: 2

      Every time someone has to change some code, you've just forced them to double their workload, and change some comments too.

      Just think of all that time wasted finding requirements and writing specifications before coding can even begin!! Who can function with such a multiplied workload.

    8. Re:Good Comments by Cederic · · Score: 2


      I'd agree with most of what you say.

      The code I delivered last week contains a Javadoc comment for each public method, and also describing the classes. Those comments focus on what the parameters need to be, what the returns can be, and what error conditions may occur. Even this I'm worried will become obsolete if people change (for instance) the returns from a method, but don't update the Javadocs.

      The rest of the code is mostly self-documenting - the one big exception being an Internal Rate of Return algorithm, which I have used inline comments for.

      I disagree with you regarding comments about bugs - I delivered my code with a full suite of JUnit unit tests - they all pass. If a bug is found, I will replicate that bug in another unit test, and get that test to pass. Should somebody subsequently re-introduce that bug, the test will immediately fail. So I don't need to comment it, I'm actually regression testing it every time I run the test suite (approx. once every 2-10 minutes while coding).

      I do know how to code properly, I do put into practise what I know, and I still don't believe inline comments help - they distract when people are trying to read the code, they invariably become out of date and inaccurate and they seldom add value.

      ~Cederic

    9. Re:Good Comments by Cederic · · Score: 2


      Hmm, fair point.

      In practise, I tend to use descriptive names, and avoid 'loopCount', 'count', 'obj', etc. I also didn't want to quote 'n' as a variable name in my original post, as I don't use single letter variable names.

      However, the example I quoted was of the stupidity of commenting the incrementation of a loop counter, and thus loopCounter was actually entirely descriptive and correct :)

      ~Cederic

    10. Re:Good Comments by Cederic · · Score: 2

      >> Jeeze, how many of you guys have worked on a big or long running project? Comments avoid the maintenance nightmare here! Something extremely simple or only being worked on by one person needs a lot *less* comments.

      Hmm. How about a $5m project last year (plus ongoing maintenance), another project this year that has 8 people tied up for 6 months..

      Comments do not avoid the maintenance nightmare. Comments are a crutch for people who can't write proper code to begin with. Something written properly, with well factored code, descriptive method and variable and class names (java bias here if you hadn't noticed) does not require inline comments every other line of code.

      As the parent to your post mentioned, if you have a lot of comments, people will ignore them. If they are adding very little value, they'll be ignored even more. Which means the few parts of the code that really don't do what you'd expect, and so do need to comment, don't get noticed. And hello, here's a bug..

      >> It's funny when programming topics are discussed on /., it really brings out of the woodwork how many students, amature programmers and web programming weenies there are out there. They should try doing some real work for once.

      It's also impressive how closed-minded allegedly experienced programmers can be to adopting new practices or considering a point of view that challenges conventional wisdom.

      I have a reasonable amount of programming experience. I don't have as much as (e.g.) Martin Fowler, Kent Beck, Steve McConnell, the Gang of Four. So I read their books, I listen to what they are saying, and I try and change how I work to use the advanced techniques that make them so damn good at what they do.

      Since a lot of the literature I read suggested "If you need a comment, your code needs to be re-written such that the comment is no longer needed" I decided to try out that technique. And it works. I have clearer, more readable code, and it's more maintainable - the maintainer knows what's happening, and isn't being misled by comments that don't add value.

      Don't get me wrong, I do sometimes use comments. I hate having to, but sometimes I'm just not good enough at programming to refactor some code enough for it to be clear.

      Do not assume that because I don't like comments, I am a gung-ho cowboy coder. It just means I'm not a sheep, I do attempt to improve the quality of what I do, and feedback around me suggests that I usually succeed.

      Incidentally, I'd usually comment a complex algorithm rather than a data object - the data object usually gets a class level javadoc along the lines of "This object represents a row from the X table" and a certain amount of domain knowledge is assumed - there is adequate supporting documentation (requirements, architecture, design) to give maintainers that domain experience.

      ~Cederic

    11. Re:Good Comments by hey! · · Score: 2

      I don't quite do it this way. Instead I break down each function by series of statements that accomplish some task (not worthy of its own function). Comments focus on how the state of variables and such have been changed.

      So, my code tends to look like a series of pieces like this:

      // Next we need to accomplish foo.
      code; // usually 5 - 10 lines of code
      code; // loops generally form a unit like this.
      code;
      code;
      code;
      // Foo is done; at this point either A,B, or C is true.

      In other words, I try to use comments to guide the reader to the part he should be interested in; if he is not interested in the part that does Foo, he can go to the part below it knowing that A, B, or C is true.

      --
      Post may contain irony: discontinue use if experiencing mood swings, nausea or elevated blood pressure.
    12. Re:Good Comments by God!+Awful · · Score: 2


      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!

      Pay attention to what the guy is saying before you reply. If you write good comments, then it shouldn't be too burdensome for someone to change the comments when they change the code. If you write lots of useless comments then it does become a burden.

      A few years back, I was a newcomer on a project where the incumbent programmer had already established some coding standards. These included "declare all variables at the top of the function" (which I refused to do), use Hungarian notation (which I don't mind, but use only sparsely), and put large comment blocks at the top of the function which basically reiterate everything you see in the function signature (e.g. name of function, class, inputs, outputs).

      I found this very burdensome, so I eventually created a macro to generate the function header and I only added extra details where it seemed necessary. Over time I noticed that these comment blocks were very often wrong. He would change the signature of a virtual function, and this would require changes to a billion files. Do you think he is really going to update the useless header comment on each of these functions? Not a chance in hell.

      I agree with an earlier thread. Buy Code Complete and follow its advice. Comments should either:

      1. Explain what a block (>1 line) of code does as a whole.
      2. Explain why a specific design decision was made.
      3. Explain a potential pitfall that might catch the code maintainer off-guard.

      -a

    13. Re:Good Comments by ahde · · Score: 2

      If the pro-comment advocates can't even be bothered to read and understand the comments they want to reply to on Slashdot, how can we expect you to read comments in the code. Dude gives several valid arguemnt and you talk about ordering a pizza.

  9. my work by drDugan · · Score: 2

    I use doxygen++ for C++; it's great

    about 1/4 of my lines are comments -- most all of which are incorporated into doxygen descriptions -- and the rest only appear in the sourse listings

    see http://www.doxygen.org/

    1. Re:my work by David+Kennedy · · Score: 2

      Agreed - the best form of commenting is peer-reviewed
      JavaDoc or Doxygen. I've used both and used to love
      Doxygen, it's superbly flexible and easy to use.

      It helps to gather up the real things people should be commenting; pre-conditions, post-conditions etc
      and not "Infinite loop".

      Plus it looks nice presenting your docs on a
      website as part of the nightly build, or printed
      out as a (huge) pdf book. All for no hassle.

  10. Use plenty of expletives by oingoboingo · · Score: 5, Funny

    Well commented code should definitely contain a liberal smattering of four-letter expletives, eg:


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

    1. Re:Use plenty of expletives by laserjet · · Score: 2

      My favorite is:

      //fucking piss drunk... not sure why this works, but will fix later.

      --
      Moon Macrosystems. Sun's biggest competitor.
    2. Re:Use plenty of expletives by Zocalo · · Score: 3, Funny
      Well the linux kernel certainly qualifies then...

      [admin@frodo linux-2.4.9-31]# grep -r [Ff][us]ck * | wc
      134 1327 10723
      Detection of the other expletives is left as an exercise for the reader...
      --
      UNIX? They're not even circumcised! Savages!
    3. Re:Use plenty of expletives by Tim · · Score: 2

      Uhh...use [us] and you'll get a bunch of fscks, which may actually be legit.

      I counted 26 legitimate guns n' roses references in the linux-2.4.2 source.

      --
      Let's try not to let fact interfere with our speculation here, OK?
    4. Re:Use plenty of expletives by Anonymous Coward · · Score: 4, Funny

      Until someone runs nm on your executable and finds some "funny" variable names.
      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.

    5. Re:Use plenty of expletives by BlowCat · · Score: 2

      But how did the customer know whether IsAFuckingIdiot is 0 or 1 in their environment? It looks like they were upset about their own assumption.

    6. Re:Use plenty of expletives by hughk · · Score: 2

      A good one to leave for QA is 'FIXME:'. At some point I sprinkle a few of these during development whilst I'm sortuing things out. Of course, I scan through and remove them. On one occasiion, I forgot to remove the comment though - whoops!! QA were not amused

      --
      See my journal, I write things there
    7. Re:Use plenty of expletives by markmoss · · Score: 2

      "//FIXME" is a pretty good way to flag sections that aren't complete yet, so a simple search will find them later. Just don't forget to remove these comments. 8-)

    8. Re:Use plenty of expletives by catfood · · Score: 2

      Years ago. Death March project. I'm the subcontractor. Client is out of control, has unacknowledged turf war between factions that want totally different features. Client management refuses to settle the dispute. Specs change wildly. Primary contractor goes along with client. Many fifteen-hour days ensue. Wife threatens to move in with parents.

      I get my part of the code into a decent state, document where I'd fulfilled specs in contract, document where I'd agreed to go beyond original contract, document where some stuff wasn't perfect but was agreed to be out of scope and not to be relied upon.

      Another contractor takes a crack at a different part of the system, different set of features. But it's spaghetti code; the other contractor has some need to make changes in my code and does so.

      Finally I get the system back again for further features. I see the other contractor's changes in my code. I find reasonably good code... with variable names like "IdiotCatfood" and "CatfoodSucks". Apparently the other contractor doesn't appreciate what I'd left him. (Nobody had told the poor guy that the spaghetti-nature long predated my involvement. He blamed me.)

      Anyway, the chosen implementation language doesn't have an option to strip debugging information.

      Oops. Other contractor got a talking-to. Heh.

    9. Re:Use plenty of expletives by jeremyp · · Score: 2

      //TODO: what needs to be done

      has a more neutral sound. It doesn't imply that there is a bug needing to be fixed that the coder couldn't be bothered with.

      --
      All I want is a secure system where it's easy to do anything I want. Is that too much to ask ~~ Randall Munroe
  11. Doxygen, etc by Stary · · Score: 5, Informative

    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
    1. Re:Doxygen, etc by CynicTheHedgehog · · Score: 2

      Javadoc is a godsend. If you do object-oriented code correctly, all of your methods will be a manageable size and shouldn't need a lot of documentation. And unless you're actually modifying a class, all you really need to know are what methods are available, what their arguments are, and what their return values mean. Javadoc handles this wonderfully.

      The biggest problem I see, however, is with procedural programming. When people do things like use complicated loop logic to avoid recursive algorithms it can be a pain to decipher. But if things are properly broken out into modules and given meaningful names I have found that I can usually handle it.

    2. Re:Doxygen, etc by arkanes · · Score: 2

      Hear hear! Here's an example - someone wrote up a delphi module wrapper to zlib. It's a great, nicely written piece of code, but theres not a scrap of documentation. By the time I finished reading the source, figuring out what the new methods for the new streams did, which object I needed for my project, etc, I could have writting my own library. I probably should jot down what I worked up and send it back to the author....

    3. Re:Doxygen, etc by slamb · · Score: 2
      Comments should only be used when absolutely necessary, which is maybe 10% of what doxygen requires.

      What gave you the idea that doxygen requires you to add a fixed number of comments? If you set EXTRACT_ALL in the doxygen configuration file, then it will generate output for all classes/functions/#defines/whatevers, whether they are documented or not.

      In fact, I find doxygen is useful even for libraries which do not use its documentation comments at all. It generates other helpful things, like inheritance/collaboration/dependency diagrams(*) and quick summaries of the members of a given class.

      So simply turn on that option and make the 10% of comments you feel are necessary. Run doxygen. I think you will be pleasantly surprised at the results.

      (*) - If you don't see all these diagrams in your doxygen, you probably haven't installed AT&T's graphviz or haven't told doxygen that it is present. And I think each can be toggled in the config file individually. Take the time to download this software and turn on the options.

  12. Different parts of the brain by heretic108 · · Score: 2, Informative

    I also have seen my share of other people's code.
    Quality of comments varies.
    I've seen code from the 'hardcore hacker', who believes that the statements themselves suffice as comments - 'the code is intuitively obvious, and it comments itself'.
    I've also seen code from complete lamers, who dilute the code terribly with irrelevant shit:

    i++; // increment i

    Over the years, I've noticed that composition of code, and commenting/documentation of code, tend to draw on two different parts of the brain.
    Often, I find myself in a 'zone', where the code flows freely, and where commenting code feels like a total distraction.
    Other times - for instance, when I'm hunting an elusive bug, I find a different part of the brain kicking in - and at that stage, I find it easier, even pleasurable, to add meaningful comments, to change indenting, variable names etc, as if I'm narrating the code to someone else.
    I guess it's a matter of balance, and using the right mental faculties at the right time.
    A good rule of thumb is to imagine that someone else is sitting beside you, someone less acquainted with the task than yourself (eg a non-technical manager). Imagine you're explaining to him/her how the code works, and put these explanations in the code as succinct yet clear comments. Imagine this person asking you, 'what's that variable'. Don't be afraid of global search'n'replace of identifier names across all the applicable files. And imagine this person sometimes getting up and leaving you in peace, so you can have those precious moments to hack to your heart's content.
    In conclusion, I feel that much of a person's personality can be read from one's code. Is someone fundamentally easygoing and helpful, and caring about others? Or is someone a complete egotist, emotionally shut down almost to the point of autism? In my mind, the ability of code to communicate its intent and methods to other programmers is almost as important as the code successfully performing its task, since its communicability directly affects the ability and interest of others in working on it, and thus its openness to manpower leverage.

    --
    -- In the beginning was the WORD, and the WORD was UNSIGNED, and the main(){} was without form and void...
  13. It's been a long time but.. by NewtonsLaw · · Score: 5, Interesting

    It's been quite a while since I wrote any significant amount of code but after spending far too many years cutting code too early in the development process I eventually woke up to the fact that coding is the *last* thing you do (apart from testing and debugging that is).

    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.

    1. Re:It's been a long time but.. by emag · · Score: 3, Interesting

      This is a technique I hope to follow with a few "personal" projects that I'm about to start. I'm refusing to write any code until I get down at least a spec for what each section is supposed to be doing.

      Alas, since the UI is wholly divorced from the back-end (I discovered I'd designed in my head an n-tier system just by seeing what I hated about both similar and unrelated software I've been forced to work with), I'm not sure I could follow everything precisely the way you suggest. After all, in the overall design, there will actually be several clients, each displaying data appropriate to its interface (web vs. fat client vs. text vs. scripted API vs. ???). I know what I can, and in fact must, do is define just how the "back end" (in terms of the clients) tells the clients what to display, what to get from the user, etc.

      I've also got to point out that in the past, I've been guilty of the "jump right in and code immediately" method of development. Unfortunately, I didn't have much in the way of control, since we were under pressure from both upper management and the customer (they have a lot of boats and guns...) to produce code for testing immediately.

      Even though this was for a "next generation" of a system already in place, it was a complete rewrite in a language the customer wasn't all that familiar with (C++), and so they were concerned that we wouldn't be able to guarantee anything would even work, let alone within the tight timing constraints required by parts of the overall system that weren't being changed.

      We had to deal with collecting all sorts of assinine metrics, such as the SLOC (Source Lines of Code) you've mentioned. Of course, the number of comments was also a metric that needed to be collected, and so we somehow had to find time to do those while frantically trying to keep pace with specs that seemed to change arbitrarily on a weekly or monthly schedule. Assinine? Yes. Real life? Yes. The only saving graces were that we'd managed to convince everyone who made decisions that some ridiculously low SLOC count was what we were responsible for in terms of monthly performance (giving us some breathing room to do intelligent design), and regular (weekly) code reviews amongst all the developers, spec writers, and the customer, to verify that what we were doing was, in fact, correct. (Though it seemed at times that we spent the majority of the meetings teaching all of the non-developers how to code in C++)

      --
      "The urge to save humanity is almost always a false front for the urge to rule." --H.L. Mencken
    2. Re:It's been a long time but.. by Cederic · · Score: 3, Insightful


      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

    3. Re:It's been a long time but.. by Pfhreakaz0id · · Score: 2

      I been in programming for 5 years in business enviroments (and some time at a software house) and have never seen a spec even close to what you describe. You're lucky if you get a generic "business case" statement, let alone a description of the UI.

    4. Re:It's been a long time but.. by noom · · Score: 3, Interesting


      That style of programming leads to unreadable and unmaintainable code. The problem is that, in many cases, the programmer that required reams of documentation in order to write the code also requires that documentation in order to read it. The system-level become inappropriate to the evironment and language being used since the design was done "in your head" instead of "in the code.

      IMHO, detailed specs should only be done when there can be a GAURANTEE that it won't change for at least 2 years. The is is the usually the case with specs produced by groups like W3C, IETF, or the OMG, and a lot of programmers think they should copy the activities of these beauricratic organizations in their own work, where requirements can be expected to change continuously. In this environment, maintaining a detailed specification that is separate from the code is far too impractical. It's better that programmers make the code and the focus of their attention and make sure their code *deserves* to be the focus of attention (i.e. it's well written, elegant, easy on the eyes and mind, fun to take walks on the beach with, etc...).

      -n00m

    5. Re:It's been a long time but.. by sbeitzel · · Score: 3, Interesting
      Well, it sort of depends on what kind of code you're writing, doesn't it? In applications development, the dev cycle can be 1 year long or longer, with support cycles that run about 3 to 6 months.

      In web development, your dev cycle is often 3 months or fewer, with support cycles measured in days or even hours. The practice of shifting requirements up until the ship date is one that we, as professionals, have a duty to curb. If you're implementing new requirements during the final 10% of the project, then you're allowing the customer to break the project and blame you.

      Unfortunately, the nature of programming doesn't really change between those extremes: it's still a question of figuring out what the problem (the product requirements) is, designing a solution to the problem (writing a spec and, hopefully, designing it so that three cycles from now when you get a requirement to change the product, you can), and then writing the code that implements the design.

      The comments we always see in these discussions along the lines of, "comments are for the weak; real programmers don't use comments..." don't take into consideration the fact that the odds are very good that you won't be supporting your own code in a year, you'll be dealing with someone else's crap. As professionals, it behooves us to provide as many clues as we can to the poor sods who'll follow after us -- because what goes around, comes around.

      When I'm doing really fast web development, the spec is often a drawing on a white board -- so I take a picture. The design is often a doodle in a notebook -- which I label and keep on my bookshelf. And when I start banging out code, the first thing I do is pseudocode in comments, then interleave the real thing. That way, when I'm interrupted in the process, I can pick up again quite easily.

      I've handed off a lot of code to other people, and I've never gotten any complaints about too many comments (or about useless ones). I have gotten comments about how easy it is to follow what I'm doing, and that's enough. Do what you need to do to get the job done, but keep in mind that the job doesn't stop with getting the thing to compile and link.

      --
      Oh, go on, check out my job.
    6. Re:It's been a long time but.. by mrdlinux · · Score: 3, Informative

      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.
    7. Re:It's been a long time but.. by Bastian · · Score: 2

      The practice of shifting requirements up until the ship date is one that we, as professionals, have a duty to curb.

      This seems like an area where software engineers could take a hint from building contractors. Once the construction begins, they aren't too willing to change the architecture. The customer had their chance to set the requirements when the plans were being drawn out, and if they can't make up their minds, tough shit.

    8. Re:It's been a long time but.. by Cederic · · Score: 2


      Total agreement - well said!

    9. Re:It's been a long time but.. by ahde · · Score: 2

      That's fine when you're doing cookie cutter coding (like business logic) but if you're doing something new, or more accurately, outside your area of experience, coding has to be done before hand to "learn" the right algorithms, UI design, etc. before you can commit to a final design.

  14. Re: Comments are evil. by dorward · · Score: 2, Funny

    The best comment is the code.

    Unless the code is Perl ;)

  15. Re:Variable Names by alpha1125 · · Score: 2, Insightful

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

    --
    Money cannot buy happiness, but can buy something soo darn close, that you can't really tell the difference
  16. Re:Variable Names by gazbo · · Score: 4, Insightful
    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?

  17. Document the function's contract by IvyMike · · Score: 5, Interesting

    Take a look at this function, and tell me if there's a bug:

    void foo(void) {
    int* x = 0;
    int y = *x;
    }

    Easy, the bug's the SEGV, right? Take a look at the same function, this time with comments:

    // Function: cause_segv
    // Description: Causes a SEGV for testing purposes
    void cause_segv(void) {
    int* x = 0;
    int y = *x;
    }

    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 function doesn't handle. It's an easy way to document the contractual obligations of the function.

    Stuff not to put in comments is stuff that's easily devised from the code. Check this out:

    // Function: square
    // Inputs: int x
    // Outputs: int
    // Used by: pythagorean(int,int)
    // Description: returns x squared
    int square(int x) { return x*x; }

    Did the "Inputs" or "Outputs" add any value? That information appears again, two lines below in the function definition, and it's guaranteed to be correct there (unlike the comment which will be out-of-date and wrong when we change "square" to work on longs). The "Used by" might have added some value, if it was correct, but as it turns out it's out of date, and 15 other functions now use "square". Any information better derived looking at the code should be left off. Any information which can be better found using "grep" or "find in files" should be left off. Any information that will probably be out of date at some point should be left off. Heck, in this situation even the description is probably extra verbiage, since it doesn't really help anyone. (I'd probably put it in out of habit anyway, though...so sue me:)

    1. Re:Document the function's contract by Darth_Burrito · · Score: 2

      Did the "Inputs" or "Outputs" add any value?

      Yes, peace of mind. I regard comments like this as a sort of promise between me and the guy who comes later. My way of saying, whatever it is, it will have the standard function header. ("used by" is silly though)

      Besides, who knows if some yahoo is gonna go modify the x squared function to do something more complicated? If there is a full function header there, the coder is much more likely to comment his change. Where I work, nobody uses function headers and comments are far and few between. I started putting headers in everything I wrote with a changelog section at the bottom. A few months later I noticed people (who almost never wrote comments) were actually putting entries in the function changelogs when they made a modification.

  18. Examples.. by popeyethesailor · · Score: 5, Funny
    # all of these will also get moved elsewhere

    # this is the worst damned warning ever, so SHUT UP ALREADY!

    # Keep your friends close but your enemies closer.
    # Or ignore them, we don't care.

    # You know, we do assume comments are linear -Brian
    Refer here for further details:)
  19. from /usr/src/linux/Documentation/CodingStyle by mav[LAG] · · Score: 2, Informative

    comes this advice:

    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.

    Generally, you want your comments to tell WHAT your code does, not HOW. Also, try to avoid putting comments inside a function body: if the
    function is so complex that you need to separately comment parts of it, you should probably go back to chapter 4 for a while. You can make small comments to note or warn about something particularly clever (or ugly), but try to avoid excess. Instead, put the comments at the head
    of the function, telling people what it does, and possibly WHY it does it.


    --
    --- Hot Shot City is particularly good.
    1. Re:from /usr/src/linux/Documentation/CodingStyle by mav[LAG] · · Score: 2

      Writing obvious code is a good idea if that coding style doesn't interfere with the problem. If your code needs to do its job in a very limited timeframe (or under other constraints), then it's possible that the "understandable" code isn't fast enough.

      This is a very good point, although bear in mind that the advice is from the source distribution of the Linux kernel which does tend to have to do its job in a limited timeframe :)

      I find when writing assembly that it's always a good idea to include a snippet of (debugged and tested) C in the comment header to a function if the code is anyway unclear. It can be read and comprehended almost instantly compared with say, a page of asm code.

      --
      --- Hot Shot City is particularly good.
  20. Multiple passes to your code by fractaltiger · · Score: 4, Insightful

    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.

    --
    "Wireless : LAN :: Laptop : Desktop"
    1. Re:Multiple passes to your code by joto · · Score: 2

      Well, if it's like a 20 page nested if/switch-statement, then comments like that are not superflous, even if you use a good editor. Of course, I don't think 20 page nested if/switch-statements are a good thing, but I have encountered them before. (I had to use indent, a printer and a ruler to see the program-flow). And sometimes you don't have the time or energy to refactor it all (although I would refactor the things I was working on). In that case, adding a few comments like that can really help the people who have to look at the code after you (now you just have to hope that people will not invalidate those comments when they are adding more cruft, because there is hardly a more confusing thing then comments out of date, or simply misleading comments).

  21. PDL it is good no? by ZanshinWedge · · Score: 3, Interesting

    Personally, I like documenting backwards. Start with the requirements, work to the architecture, then get into writing PDL (Program Design Language). Essentially, you write out as detailed instructions on what the routine does as you can, without getting to the nitty gritty. It describes the intent of the code, not the code itself. It morphs into excellent comments when you expand it out into full code, and it also has the nice little advantage that it's at a high enough level that it's applicable to multiple languages (if you should desire to switch).

  22. Linux and other things. by jon_c · · Score: 4, Insightful

    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.

    --
    this is my sig.
    1. Re:Linux and other things. by rnd() · · Score: 2

      It depends on your target audience. As a spectator, a page of comments before each function is fine. But if you are a novice programmer and you want to straightforwardly understand the techniques used, more of a line by line approach would be more useful. I personally like a bit of high level as well as some low level commentary to make the code easy to read quickly.

      --

      Amazing magic tricks

  23. Re:Variable Names by emag · · Score: 5, Insightful

    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.

    --
    "The urge to save humanity is almost always a false front for the urge to rule." --H.L. Mencken
  24. Why not what by joss · · Score: 2

    It's real simple. If the reader can't tell what the code does from reading it, either it's written badly, or the reader is incompetent. In either case, comments won't help. If I see too many obvious comments, it's a clue that the author was clueless and I should probably just throw the code away because it will cause more trouble than it fixes.

    When comments are useful is to fill in information that is obvious to the author but not obvious to anyone else reading the code. When the author wrote the class/function he knew why he was doing it, why the function was needed at all, this kind of information allows a new developer to get an overall understanding of the project much faster.

    --
    http://rareformnewmedia.com/
    1. Re:WHY not WHAT by cr@ckwhore · · Score: 2

      I agree with that! Not only for the benefit of others, I usually find the WHY in my comments to be beneficial to myself when I go back to a piece of code 6 months later.

      --
      Skiers and Riders -- http://www.snowjournal.com
  25. code comments by VonKruel · · Score: 2, Insightful

    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 :-)

  26. Re:type* var is evil by Twylite · · Score: 2

    OTOH, char* foo is arguably more logical than char *foo. You are declaring foo as being of type "character pointer". You are not, in fact, declaring a char with a pointer to it named foo (you never declared the char, only the pointer), which is what is implied by your recommended form.

    --
    i-name =twylite [http://public.xdi.org/=twylite], see idcommons.net
  27. Pseudo code and formatting by silentbozo · · Score: 2

    I explain what each function is supposed to do, along with any assumptions I'm making and any desired side-effects that the coder should expect. If I'm using algorithms beyond a basic for loop, I'll stick pseudo code with example inputs and outputs in the comments as well.

    Function and variable names that make sense go without saying - they may be a pain to type in, but in the end they don't hamper code efficency, so make them as self-explanatory as possible (with exceptions like using i and j for a 5 line for loop.) Remember, whitespace and good, CONSISTENT formatting is just as important as good commenting. Funky, inconsistent formatting pisses me off just as badly as cryptic commenting and 6-character all-capital variable and function names.

    I comment under the assumption that the next time I look at this code, it will be years later and I'll have forgotten much of the programming language I originally wrote the code in (basically, I assume the next time I look at the code, I'll need to port it.) In instances like this, basic descriptions of what a function is supposed to do, along with pseudocode of the alogrithm with sample inputs and outputs are EXACTLY what I need - not to mention, they serve as a road map for when I'm writing and debugging the code the first time. Typically, I'll have just as much commenting as actual code for simple stuff, for anything beyond that I'll have double as much commenting as code (readable english is less efficient than clean code, so what do you expect?)

    You should always look over and polish both your code and your comments before you shelve your code. If you're leading a team, it should be your code that sets the bar for good logic, commenting and formatting style. Even if you're not, good maintainable code is what they're paying you do write (I hope.) Of course, if they aren't paying you enough to write clean, commented code, then they get what they're paying for...

  28. Proper Commenting of Code by joe52 · · Score: 2

    I thought that commenting was only supported to prevent a block of code from being compiled (or even better, dozens of little fragments of code).

    What is all this about using comments to document what you are doing?

    1. Re:Proper Commenting of Code by silentbozo · · Score: 2

      Nah, that's what if statement blocks with conditions that never will be met are for. That way you preserve the bulk of your unused code when you compile your binary, so you can bloat your release and have it shipped on a couple of CDs. Not to mention it confuses the hell out of the Q&A guys.

    2. Re:Proper Commenting of Code by rtaylor · · Score: 2

      There is nothing wrong with:
      if (true == false)
      printf("World Ending");

      --
      Rod Taylor
  29. Have a standard by Paul+Johnson · · Score: 2
    On a large project a key to getting anything done right is to have a standard and check that people stick to it. Code reviews are a Good Thing in any case. Checking that the comments say useful stuff should be part of this.

    Every file should start with a preamble giving module name, version, author, and maybe revision history. Most of this can be generated automatically by your version control system.

    Then there should be anything from a few sentences to a few paragraphs saying what problem this module solves and how it does it. Refer to any other documentation (e.g. UML diagrams, textbook for the algorithm) that might help illuminate what is going on.

    Each function or data structure should have a similar comment explaining what it does.

    Avoid comments that say "this routine is used by the Foo Function to update the Bar structure". Instead just say "This routine updates the Bar structure such that...". If the routine makes no sense on its own then it probably shouldn't be on its own.

    Paul.

    --
    You are lost in a twisty maze of little standards, all different.
  30. Location, location, location by ralphbecket · · Score: 2, Insightful
    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
  31. Re:type* var is evil by emag · · Score: 5, Insightful
    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...)
    --
    "The urge to save humanity is almost always a false front for the urge to rule." --H.L. Mencken
  32. Hungarian Notation (Ugh!) by caveman · · Score: 2, Insightful
    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 (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.
    1. Re:Hungarian Notation (Ugh!) by JKR · · Score: 2, Insightful
      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.

  33. Check out how not to do it. by chrestomanci · · Score: 2, Interesting

    See: How To Write Unmaintainable Code by Roedy Green

    Every time I read it, I laugh from all the crazy examples of how not to do things:

    eg:

    16: Names From Mathematics:
    Choose variable names that masquerade as mathematical operators, e.g.:
    openParen = (slash + asterix) / equals;

    1. Re:Check out how not to do it. by Amazing+Quantum+Man · · Score: 2

      my contribution was...

      Abuse the preprocessor! Use global variables everywhere, and write the entire code in macros that manipulate those global variables!

      Disclaimer -- I once inherited code from a jerk who did this. First thing I did was run the preprocessor and essentially rewrite the code.

      --
      Fascism starts when the efficiency of the government becomes more important than the rights of the people.
  34. Re:Simple rule of thumb by nagora · · Score: 4, Interesting
    Write code that is easy to understand and comment about wierd / unusual sections

    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

    --
    "Encyclopedia" is to "Wikipedia" what "Library" is to "Some people at a bus stop"
  35. Comments Considered Harmful by Bazzargh · · Score: 3, Interesting

    This has come up before - in Martin Fowler's book, "Refactoring", he makes the controversial claim that sometimes comments are indicative of a need to change the code.

    Consider the different types of comment:
    - boilerplate comment at the top of a file: helps noone but lawyers.
    - change history comment: better use your source control tool to maintain this.
    - comment before a class: does this mean the class is badly named, or too complex?
    - comment before a method: ditto.
    - comment inside a method: could be a smaller method screaming to get out.
    Also heavily commented code is quite commonly just explaining away stupid code tricks.

    Nobody's suggesting that all comments are bad, just that a lot of the time adding comments is a poor substitute for fixing whats wrong with the code. Of course sometimes its the language thats the problem :)

    -Baz

    1. Re:Comments Considered Harmful by scrytch · · Score: 2

      Yunno, I'm really getting sick of Fowler's "worse is better" nonsense trying to win back the day for "cowboy coders" who can't handle any discpline at all and want to treat critical production code as a playground. I'm starting to think that projects are succeeding in spite of his "methodology" , and not because of it.

      - boilerplate comment at the top of a file: helps noone but lawyers.

      Meaninglessly vague. Is javadoc boilerplate? I don't like a stupid compiler that isn't self-documenting (hint, emacs is) but until then, we have this.

      - change history comment: better use your source control tool to maintain this.

      This guy must have a massively cool source control tool that actually shows him the changelog on a per-function basis, and automatically senses and shows only the changes that are significant, like an interface change. Or should every developer memorize today's changelog?

      - comment before a class: does this mean the class is badly named, or too complex?
      - comment before a method: ditto.


      The latter. We don't always get to write everything from scratch. Much less rewrite it 10 times a day for fun.

      - comment inside a method: could be a smaller method screaming to get out.

      Another smaller, uncommented method, no doubt.

      --
      I've finally had it: until slashdot gets article moderation, I am not coming back.
    2. Re:Comments Considered Harmful by Sajma · · Score: 2, Interesting
      Actually, I've found Fowler's technique for extracting methods pretty useful for clarifying code. Basically, he says that if a block of code is preceded by a comment, extract that block into a method whose name is the same as that comment, and remove the comment.

      This works pretty well, and leaves you with two kinds of methods: top-level ones that look like simple lists of tasks (enqueueEvent, sendReply, etc.), and small lower-level methods that do only a specific task. And yes, these small methods usually don't need to be commented, because the method name serves as the comment.

      This technique also works well for replacing ugly boolean formulas in if-statements. Compare

      // check if message is late, and if so, do blah
      if (System.currentTimeMillis() > (message.timestamp() + Message.TIMEOUT) {
      // blah
      }

      to

      if (message.isLate()) {
      // blah
      }

      I'd argute that the latter doesn't really need a comment.
    3. Re:Comments Considered Harmful by scrytch · · Score: 2

      Good explanation ... I stand corrected. mod parent up. I'm not fond of comments in general either -- I'm a fan of the SCID (source code in database) concept that would allow for cleaner separation of code and comment, such that boilerplate need not be inlined, leaving inline comments for only critical things. However, while we're stuck with flat files, it's never a good idea to eschew stuff like javadoc/doxygen "boilerplate" for any public method except perhaps simple accessors (and a setter should still document expected input).

      --
      I've finally had it: until slashdot gets article moderation, I am not coming back.
    4. Re:Comments Considered Harmful by smallstepforman · · Score: 2

      You're obviously one of the group of people who just dont get it. After 'seeing the light', I organised a quick presentation at work to introduce my collegues with Fowler's wisdom, even prepared a few pages as a presentation. I even asked my boss to get a copy of the book for every developer. I must be a bad presenter, because only 2 other people (out of 13) saw the benefits Refactoring brings, and decided to study the book. The other 11 thought (just like you) that Refactoring was bollocks. Out of curiosity, what do you think of the 'Gang of Four' book?

      As I said, I must be a bad presenter.

      --
      Revolution = Evolution
    5. Re:Comments Considered Harmful by Bazzargh · · Score: 3, Interesting
      I see you've gone back on the post a little later but its worth answering some of your points.

      Yunno, I'm really getting sick of Fowler's "worse is better" nonsense trying to win back the day for "cowboy coders" who can't handle any discpline at all and want to treat critical production code as a playground.

      Fowler's stuff isnt cowboy at all. It actually takes a lot of discipline to follow what he actually says in his book (writing tests to ensure that each refactoring is safe). His book is a series of recipes for how to introduce changes safely, not a rally call for changing code because you feel like it today. The Refactoring book can help people working in any methodology (except perhaps the 'Personal Software Process' and its variants, which want you to learn to write code right first time, and are less realistic for code maintenance). XP gets a mention but its not an XP book.

      Meaninglessly vague. Is javadoc boilerplate?

      Meaning 1 on wordnet is "a standard formulation of legal documents or news stories". Now look at this (code from Tomcat). See the boilerplate comment at the top? Its NOT THE JAVADOC - its the license. There are tools like jalopy which help you maintain this cruft but like I say it helps noone but lawyers.

      This guy must have a massively cool source control tool that actually shows him the changelog on a per-function basis, and automatically senses and shows only the changes that are significant, like an interface change.

      The 'change history comment' is the old practice of writing in a history of changes at the top of the file (not on a function by function basis as you suggest) duplicating the comment recording in the source code control system, while not necessarily recording all changes because it isnt /driven/ by that system. VSS, CVS, etc can show you the changelog externally, or you can include a $Keyword$ to get the changelog included in the comment and maintained for you. As for knowing which change is significant - developers don't know this either. The change which breaks things is the significant one and they usually don't realise they've done it at the time. Interfaces changes, while high cost, are actually less significant causes of error since they are easily caught by static checks. It is the changes in behaviour that will get you.

      We don't always get to write everything from scratch...

      This is true. often you'll not get to rename the methods of some dumbly named third party interface. And in this case the comment is inevitable. Note I did say not all comments are bad. I'm asking you to question them.

      Another smaller, uncommented method no doubt.

      Yes, exactly. If the smaller method is 4 lines long, has a blindingly obvious name, and is in the private interface of the class (often the case for extracted methods like this), the comment is superfluous.

  36. Design by Contract by MosesJones · · Score: 2


    A couple of words, OCL

    This is in the interface, rather than an implementation, and you won't get the code to the impl, so what does it do ?

    /**
    * Get the Bug description for the given Id
    * @pre id must be > 0 and less than BugList.lastId(), the highest bug number
    * @post The return must not be null
    * @invariant does not change the number of bugs
    */

    Well that is the comment block, not all of it because there is some OCL in there, but I thought I'd leave something for Google. The point is that the description describes exactly what the method does, it also says what the caller must do or face the consequences, and what the caller can rely upon when the method returns.

    And for any one who says comments aren't required if you write the code well enough... you are a muppet. Interaction via interfaces is a basic tennent of coding, .h files anyone ? You shouldn't have to look at the code.

    --
    An Eye for an Eye will make the whole world blind - Gandhi
  37. comment the data structures too by digital+labourer · · Score: 2, Informative

    It is not only executeable code that can benefit from comments. In particular any numeric fields should have a units comment (e.g. m or m/S). It can be quite time consuming to deduce the units from the code.

  38. Re:type* var is evil by Tony-A · · Score: 2

    If it takes splitting hairs to get the scopes right, then better split hairs.
    char* foo, bar;
    looks like: (char*) ((foo),( bar));
    behaves like: (char)((* foo),( bar));

    You get the same effect from:
    y = x * a+b;

  39. Re:Simple rule of thumb by nagora · · Score: 2
    That's not a good idea at all. That encourages rambling pointless text, not quick precise explanations.

    Quick explanations are rarely precise explanations when programmers are involved.

    Anyway, keeping documentation longer than the code encourages shorter code more than it encourages rambling text, unless you know programmers that like typing more than I do.

    Short code with a good explanation is always better than long code with poor explanation. In fact, short code is always better, period. Every line of code beyond what is needed for the task should be rooted out; it is a source of bugs and inefficiency.

    TWW

    --
    "Encyclopedia" is to "Wikipedia" what "Library" is to "Some people at a bus stop"
  40. Document abnormal behaviour by tve · · Score: 2, Funny

    1. Adopt some set of coding conventions. For instance, always return 0 on success/in the normal case.

    2. Use informative variable and functionnames. Short names are preferred, but make sure it's clear what you mean. If it's impractical to fit all the required info into the var- or functionname, add a comment explaining the intended purpose of the variable/function.

    3. Use small functions! Split actions up into logical steps. In combination with 2 this will help make your code a lot more readable, removing the need for many comments. Like Linus says: "The maximum length of a function is inversely proportional to the complexity and indentation level of that function."

    4. Document any abnormal behaviour. For instance, if you've adopted the convention that functions return -1 on errors and you have a function that differentiates between different errors by returning either -1 or -2, document what the abnormal return values mean.

    5. If the overall purpose of a group of functions (e.g. in one sourcefile) isn't obvious, add a general comment that explains the big picture. Code is much more readable if you know what it's trying to do.

    --

    If there is hope, it lies in the trolls.
  41. Work from the top down by Daetrin · · Score: 2, Interesting
    I recently ran into two functions in the code base I'm using that were titled "ObjectTrackDirection" and "ObjectTrackToDirection". The similarity in names was annoying, but the criminal part was that neither function had comments indicating what they did, or what the difference between the two was. In fact, the only comment in either section of code was on one line that was duplicated in both pieces of code, and which said "not sure why this is needed". This did not give me a great deal of confidence as I started out trying to decipher what exactly these functions were supposed to accomplish differently.

    No matter how clear you think you made the name of the function, there should be a comment explaining what the fuction is supposed to be doing. If the function accepts a lot of flags or variables you should briefly explain what they're each used for.

    Knowing what the function is supposed to accomplish is a big step forward, even if there are no other comments at all.

    If you're still willing to keep at it, start commenting the big blocks of code in the same manner. What are you trying to do with this loop? Why are you testing for these cases in this if statement, and if it succeeds, what are you trying to do inside of it?

    Always go in favor of more comments. I would rather have to skim by a dozen comments that I don't need to read than be left hanging for the lack of one comment when something goes wrong.

    And finally, always use whatever comment system your source control program uses! Even if it's just "I did some stuff to fix some problems with A," because if I later find out that a particular case of A is broken, I don't want to have to do a diff on every single code change made since the last time I knew that case of A worked.

    --
    This Space Intentionally Left Blank
  42. My favorite comments by bentini · · Score: 5, Funny
    I personally despise comments such as:

    i++; //increments the variable i

    I think that they are unclear and do not properly explain the situation. Remember, you're writing so people can UNDERSTAND the code, not so that you can impress them with how smart you are. Instead, strive for a comment like this:

    i++; /*changes the value stored in the space referred to by i to be the sum of the old value stored in the space referred to by i and the constant 1. Note: In C, this may cause what is known as a "silent overflow" if the value is too large, and go so far as to make a large positive value into a larger negative one. Oh my!

    This way, people who read your code not only understand your program, but all programs. I really think that each function you write should repeat a semester's worth of computer science theory and programming practice, so that anyone who reads your code will learn from it. Remember, not everyone knows idioms, and why should they? And since we all write open source on slashdot, many novices are going to have their introduction to any computing environment by looking at the code you write at any point.

    Your most humble and obedient servant,
    Dan

    1. Re:My favorite comments by curunir · · Score: 2

      I like to take the opposite approach. I assume that any engineer reading my code is capable of understanding code. So I write my comments in code...even sprinkling comments in amongst my code. Take this, for example:

      int foo(int bar) {
      // report.print() if foo =~ /^[0123]$/
      if(0 == bar) // {
      printf("bar equals zero");
      /*} elsif(1 == bar) // {
      printf("bar equals one");
      } elsif(2 == bar) */ {
      printf("bar equals two");
      //} elsif(3 == bar) {
      printf("bar equals three");
      }
      }


      It should be immediately obvious to any engineer what foo(1) does.

      --
      "Don't blame me, I voted for Kodos!"
  43. Re:Braces by Ed+Avis · · Score: 2

    The best practice, IMHO, is just to follow whatever the language's author prefers. He or she is likely to have quite a bit of experience, right? And presumably if you like the language then you already agree that its designer has some degree of good taste.

    This means: for C, follow the style in K for C++ get a copy of Stroustrup's book and follow the style he uses; for Perl read the perlstyle(1) manual page; and for Java follow Sun's conventions. This gives you the best chance of interoperating with other people's code.

    Of course, if you're doing development within a larger project, such as adding code to an existing program or writing a new utility to add to OpenBSD, then you should follow the local style conventions. Just find what the local 'source of authority' is, and follow that.

    --
    -- Ed Avis ed@membled.com
  44. like a book on nutrition by g4dget · · Score: 3, Insightful
    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.

    1. Re:like a book on nutrition by Anonymous Coward · · Score: 2, Insightful

      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.

    2. Re:like a book on nutrition by Aceticon · · Score: 2

      But the real culprit when it comes to poor software are time and resource pressures, feature creep, and other environmental factors.

      THAT explains the "This is a ugly hack" comments i keep finding when going through somebody else's code!!!

  45. Re:type* var is evil by tal197 · · Score: 3, Informative
    OTOH, char* foo is arguably more logical than char *foo. You are declaring foo as being of type "character pointer". You are not, in fact, declaring a char with a pointer to it named foo (you never declared the char, only the pointer), which is what is implied by your recommended form.

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

  46. Some examples of bad comments by Dr.+Tom · · Score: 2

    i++; /* increment i */

    a = b; /* save the value of b */

    /* this function calculates theta. */
    float theta(char **p, int d, float *(*fn)(int))
    {
    ...
    }

  47. Re:type* var is evil by Ed+Avis · · Score: 2

    There was once an article linked from Slashdot ('tips for C programmers' or the like) which explained this clearly - but I can't find the link now :-(. Essentially, you have to consider the C declaration syntax as a kind of logical puzzle.

    Take 'char *c'. This says that *c is a char. So what is the type of c? Working backwards, it must be pointer to char. Or with 'char (*c(int))' you can see that *c(int) has type char, so *c must be a function taking int and returning char, so c is a pointer to such a function. The cdecl tool can help with figuring out the more complex cases :-).

    --
    -- Ed Avis ed@membled.com
  48. Two basic rules by edhall · · Score: 2

    1. The code should be written so that it is clear what it does from the code itself. Descriptive identifiers, well-focused classes and single-purpose functions all help. Careful use of white space (e.g. dividing code into "paragraphs") helps. If it isn't clear what the code does, rework it until it is clear.
    2. The code should be well-commented to explain why it does what it does. Explain how it fits into the overall scheme (and make sure you've explained that scheme).

    One way of doing this is to have a comment block introduce each class and each function. If these comments are not in a standardized format, at least make them consistant. If you're using a non-obvious algorithm, this is where you should describe it, in full. If it is spectacularly non-obvious, provide a reference to a separate doc. And if your project has created design documents prior to coding, provide references back to those docs.

    Obviously, the way code is "chunked" in item (1) has a lot to do with how it gets documented in item (2), and vice-versa; I put them in that order because it made it easier to explain, though in practice much of (2) is done before (1). But the two have to be taken as a whole and ultimately completed as a whole.

    I don't know how many times I've seen comment-as-you-go code where the comments disagreed with the code, and it wasn't clear just what a function was trying to accomplish. But if I understand the goals of a piece of code, and reasonable care has been taken in naming and organizing it, in-line comments just get in the way.

    -Ed
  49. Formatting by Dr.+Tom · · Score: 2
    Sometimes you can use tools that help write docs based on specially formatted comments, but for most comments, all you want are:
    Paragraphs,
    written with complete sentences,
    using vanilla formatting.
    It is not widely recognized, but maintainability arguments apply to comments as well as code. When the code changes, the comments have to change too, and they should be easy to modify. That means no fancy boxes or other bizarre formatting. I don't care if your editor can handle automatic double column star boxes, not everybody's can, and to be portable (yes, comments have to be portable), you should use the absolute minimum formatting. For example:
    /* This is a block comment. It describes the block of code below. Notice that it uses no special formatting, and when I change the comment, I can hit the "reflow" button in the editor and it'll get reformatted like any other block of text. */
    Use inline comments sparingly. Write complete, descriptive sentences at the block level. It's also good to put blank lines before and after comment blocks.
  50. Commenting "null" code by Zocalo · · Score: 2
    There was a similar discussion here on /. not so long ago, and one post from it stuck in my mind as being perhaps the most worthy +5 post I'd read for a *long* time.

    Basically someone had been going through code and found an entire subroutine commented out with the rider "This doesn't work". The original poster went on to say (s)he'd initially missed the point and thought the commenter was dumb, until the penny dropped - this would be a massive time saver if someone else thought of the same routine.

    I have to admit, I'm not sure if this commenting practice would have occured to me - until I read this I'd always deleted broken code. It's definately something to bear in mind next to you waste a few hours working on a flawed algorithm.

    --
    UNIX? They're not even circumcised! Savages!
  51. Re:Literate programming by emag · · Score: 2

    Has this progressed much to supporting languages other than TeX, Pascal, and C?

    I have "Literate Programming" by Knuth, but there always seems to be something more important coming along that I need to read "first".

    --
    "The urge to save humanity is almost always a false front for the urge to rule." --H.L. Mencken
  52. Comments are only a part of the answer by PinglePongle · · Score: 2, Insightful
    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.
    --
    It's all very well in practice, but it will never work in theory.
  53. Tracing by slim · · Score: 2

    I write server code that will be run by another part of the organisation, on machines that I don't have access to. As a result it's useful to be able to turn on extremely detailed tracing so that the guys running the service can send us traces of sessions that didn't behave right.

    I find that the trace calls in the code are often as good as comments, in that someone browsing the code could use the traces to work out what's going on.

    e.g.
    for(lc=0;bytes_left>0;lc++)
    {
    trace("In main parsing loop, chunk %d, %d bytes remaining to process",lc,bytes_left);
    }

    ... tells us the purpose of the loop, and the purpose of two variables. Clearly putting a real /* comment */ next to the trace line would be redundant.

    I think even if I weren't tracing, I would place comments in pretty much the same places.Of course this isn't all the commenting I do -- there are certainly comments required above and beyond these, such as detailed descriptions of what a function should do above the declaration.

  54. Re:Variable Names by Grab · · Score: 5, Interesting

    Sometimes, from other ppl. If I see it, it goes right back in review, and I won't pass the review until the fuckwit responsible has removed them. If you're writing code for yourself, then fine, please yourself. If you're writing code that anyone else will see, *especially* the customer, then hell no.

    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.

  55. WHY not WHAT by mikehunt · · Score: 2, Insightful

    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.

  56. Re:Variable Names by Dynedain · · Score: 2

    a guy at my work did that with filenames regarding projects (not coding)...the day he was out of the office and the boss was looking over a coworker's shoulder as they desperately pulled the stuff they needed....well...it wasn't a good day for him

    --
    I'm out of my mind right now, but feel free to leave a message.....
  57. Things to bear in mind by Rogerborg · · Score: 5, Insightful
    • 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.
    --
    If you were blocking sigs, you wouldn't have to read this.
    1. Re:Things to bear in mind by bluGill · · Score: 2

      Maybe YOU have 256 charicters to play with, but I still have to use old systems with only 6 unique charicters to play with. Please make sure your variables and functions are unique in the first 6 letters. This isn't as bad as it sounds, I can make my variables 1024 charicters if I want to, the compiler will just silently truncate them to 6, so I can still have the long names, I just have to be careful to make the first 6 charicters unique.

    2. Re:Things to bear in mind by Amazing+Quantum+Man · · Score: 2


      But then how can you use hungarian notation?

      char *lptstrSomeString, *lptstrTheOtherThing;
      </HUMOR>

      --
      Fascism starts when the efficiency of the government becomes more important than the rights of the people.
    3. Re:Things to bear in mind by ahde · · Score: 2

      never take away i
      it'll cost you too many enemies

      instead, do

      for (i = 0; i < LASTROW; i++)

      or if you need to compare complex datatypes:

      while (! isLastRowPopulated(myTable[i]))

      or

      while (! Table.isLastRowPopulated(i))

  58. Re:Variable Names by peddrenth · · Score: 2, Funny

    $StringPlusOne = $DollarDivideBy * $HashSemicolon + 8;

    print "$EndQuote Semicolon new line";

    getURL "http$Colon$Slash$SlashSlashDot${dot} org$slash";

    ...

  59. No such thing as too obvious by Christopher+Bibbs · · Score: 2

    If a support developer doesn't know what a little used third party function does and I don't comment it, who loses? Short answer: everyone. Support development team loses, I lose, QA and/or tech support loses as they wait for a fix.

    Now, what if I (like so many other programmers and yourself apparently) have my head firmly up my ass so I think all my code is obvious in function and I only need to explain my intent? Well, after being humbled a few times, I'll figure out that it is more useful for everyone if I just use lots of comments, even things that may seem obvious once written, the role of support is vastly improved and my need to help with support is greatly reduced.

    Of course, maybe you like doing support programming, it takes all kinds I guess.

  60. Error handling makes the code hard to find? by fireboy1919 · · Score: 2

    I would say that this is part of the problem with code that you might create - you're hiding the implementation section.

    The best way to produce the code is to create a clear division between functional elements, a clear division of data elements, and a clear division of implementation and error checking. What I mean by "division" is very dependent upon the language. If you've got an OO language its clearly easier to define the difference between data types using objects than it is in a weakly typed functional language.

    However, all of these things can be done with any language. If error checking is taking a lot of space, put it in a separate function, or at the very least put some sort of divider that makes it obvious where the code begins and the debug stuff ends.

    The best comment is often well structured code. Comments only make it easier to understand those rare algorithms that can be explained in a non-algorithmic way. (Actually these aren't extremely rare. FFT comes to mind.)

    --
    Mod me down and I will become more powerful than you can possibly imagine!
  61. Too many comments? by erpbridge · · Score: 2

    A couple years ago, I took a programming class at a local community college. The whole class got failing grades for the first few assignments, even though the program did what it was supposed to do and had 4 lines of comments per routine.

    Turns out no one got any higher than a C until they made a whole page of comments for each line of code. On top of that, the teacher demanded the code be printed out.... I remember that I ended up turning in a 100 page document once, whereas the program was only about 90 lines.

    I think that's a little too much commenting, but he still said more comments needed to be made. I understand where he was coming from (he used to program in Cobol, and this was in 1998, when everyone was scrambling for patching uncommented Y2K code), but there's such a thing as overcommenting.

  62. My preferences by Piquan · · Score: 2, Insightful

    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.

  63. Re:Variable Names by Squashee · · Score: 2, Interesting
    Besides naming your variables meaningfully I have an additional suggestion. I allways (when applicable) add a prefix to my variables that identifies the type. Name then becomes sName.
    • s - String
    • i - Integer
    • f - Float
    • r - Reference
    • a - Array
    • etc...
    I know this does not work for everybody, but for me this has done wonders when it comes to understanding my own stuff a couple of months later.
    --
    When in doubt, act determined. Business 101
  64. Important to maintain comments by coreman · · Score: 2

    The biggest problem I have with going through code (as a contractor, I tend to read a lot of new "to me" code) is the case where you're dealing with 2nd or third generation code, the original developers are long gone, and the intent of the routines has changed but the header/interface comments have not. One has to read and understand the code in order to make the changes and while the comments might be helpful, they also might be outdated and wrong. Too many times I've found a comment beside a routine call that say one thing and when I go into the routine, find it's something totally different. I am especially careful about comments that talk about expected return values or side effects. These generally aren't a problem on release 1.0 code but there's a lot of jobs out there dealing with release 5 versions of things where the comments might not have kept pace with the product.

  65. One other point by coreman · · Score: 2

    Many times a group is unwilling to submit comment/non-code changes for a module (due to the return values changing say) to source control because they don't want to have so many modules change for what they see as a "trivial" fix in another module. It's tough to get some of those changes through many review procedures and this is what causes comments in "callers" code to be outdated. Use the comments as a guide, not as gospel.

  66. Re:Variable Names by GigsVT · · Score: 2

    What happens when you recast it to something else?

    --
    I've had enough abrasive sigs. Kittens are cute and fuzzy.
  67. Re:type* var is evil by Twylite · · Score: 2

    You missed my point entirely. *foo is not a character. *foo is a pointer, and under ideal circumstances it is going to point to a character. *foo is not a character because you are not declaring a char variable, you are declaring a pointer variable.

    Saying that *foo is a character implies that you can do something like *foo = 'A';. Which, surprising as it may seem, you can't. This is usually referred to as a "segfault" or "bug". But if you first assign a value to the pointer so that it actually points to something, then you can access a character at *foo.

    --
    i-name =twylite [http://public.xdi.org/=twylite], see idcommons.net
  68. Re:Braces by thogard · · Score: 2

    The one true brace style as defined by K&R puts the braces on the same line as the else and if statements since they control the flow and the braces are just there for grouping.

    int foo(bar)
    {
    if (something) {
    // code
    } else {
    // more code
    }
    }

    Thats 8 spaces to the tab for older stuff and 4
    for newer stuff.

  69. Re:Coding Standards by GigsVT · · Score: 3, Funny

    Other things, such as always including { and } in C, and putting them alone on their own line

    Phew, I thought I was alone. I'm glad it makes sense to someone other than myself to actually have the braces line up vertically.

    --
    I've had enough abrasive sigs. Kittens are cute and fuzzy.
  70. Re:Variable Names by Aqua+OS+X · · Score: 2

    hehe, if one was to view the source of a big web site that I made, they'd probably run into quite few JS variables with names like "ihateExplorer" or "ihateNavigatorfour"

    --
    "Things are more moderner than before- bigger, and yet smaller- it's computers-- San Dimas High School football RULES!"
  71. Over commented example by ch-chuck · · Score: 2

    My favorite example of well commented code, to the extreme, was a text editor w/ assembly code published in a Byte mag about 1983 or so (VDO Video Display Oriented). The source listing was nicely broken down into functions with a paragraph explaining exactely what was going on and why for maybe every 2 or 3 instructions! Anyway, the amount of English text far outweighed the actual code by maybe 10 to 1.

    --
    try { do() || do_not(); } catch (JediException err) { yoda(err); }
  72. Re:type* var is evil by Twylite · · Score: 2

    I would argue that int *foo means foo dereferenced is a segfault unless you've assigned a meaningful value to the pointer foo.

    Or, to take your conclusion: In this: 'char foo, *bar', we declare that two things have type 'char': foo, and the thing that bar points to. Wrong, you haven't declared the thing that bar points to as type char. You haven't declared it at all. Which is precisely the sort of misunderstanding that I'm saying your style of declaration leads to.

    In char *bar you have declared a pointer, and some assumptions about the pointer. You have not declared a char. There is no memory allocated to that char, nor any type checking implied about the value that bar may point to unless accessing it through bar. In other words, you have declared nothing at all about what bar points to, but rather a constraint on the use of the pointer bar.

    In other words, char* foo clearly declared foo as a pointer, whereas char *foo defines *foo as a char, and by implication foo as a pointer, but no char is every actually declared.

    --
    i-name =twylite [http://public.xdi.org/=twylite], see idcommons.net
  73. Describe your design decisions and thought process by mfarah · · Score: 2

    I'm currently developing a project where I have to modify existing source code developed by someone else. I spend most of the time trying to figure out WHY the previous programmer did something the way he did it, and what the hell he was thinking. Write these into your comments. Also, write down in comments small tips for the programmers that might come after you. Comments in the style of:

    /* This function expects an object that has been fully filled and checked for errors before. Be sure to never send it a NULL one! */

    or

    /* We're invoking the call to the database with the "mode" flag set to zero because currently it won't use it - but it COULD be used in the future. */

    help a lot.

    I also have to modify Java source, where I have generic classes that inherit from previous ones a lot of attributes. For example:

    public class A {
    public String s;
    public double d;
    public long l;
    }


    and

    public class B extends A {
    public String ss;
    }


    I prefer to write class B like this:

    public class B extends A {
    // public String s; : A
    // public double d; : A
    // public long l; : A
    public String ss;
    }


    That way I can see quickly all of the attributes class B contains.

    --
    "Trust me - I know what I'm doing."
    - Sledge Hammer
  74. Favor Code Clarity Over Comments by Bob9113 · · Score: 5, Insightful

    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.

    1. Re:Favor Code Clarity Over Comments by barzok · · Score: 2

      I never liked putting "not" in a variable name like this. It makes if statements later on klunky to read. Using if (!isNotNull) to determine if something is null can be difficult to wrap one's head around. I prefer to use the positive case:
      if (isNull) {
      do something
      }
      else {
      do something else
      }
      I think you'll find that in Code Complete (previously recommended in this story) as well.

    2. Re:Favor Code Clarity Over Comments by Bob9113 · · Score: 2

      Upon further reflection, I think that the following is just as clear in setting definedForThisUi, and also makes the use of !'s clearer. Your recommendation makes a lot of sense.

      private void initialize( Task aTask ) {
      String initializerName = task.getInitializerName();
      boolean isNull = initializerName == null;
      boolean isEmpty = "".equals( initializerName );
      boolean definedForThisUi = ( ! isNull ) && ( ! isEmpty );
      if( definedForThisUi ) {
      addToTaskBar( aTask );
      }
      }

      Thanks for the tip!

    3. Re:Favor Code Clarity Over Comments by lkaos · · Score: 2

      I'm sorry, but your second example is ridiculus. Moving comparisions outside of the if statement and introducing three extra named variables is not only horribly inefficent, but makes thing unnecessarily complicated.

      Things like null comparisions do not need to be commented. Everyone knows what your doing if you have 'aClassName != null'. There is no need to waste disk space but restating the obvious.

      --
      int func(int a);
      func((b += 3, b));
    4. Re:Favor Code Clarity Over Comments by Permission+Denied · · Score: 2
      I disagree. Your first example is good, concise code, while your second is far more difficult to read. If you want to express something, why not use English?

      Why would you ever do this:

      boolean definedForThisUi = isNotNull && isNotEmpty;
      if( definedForThisUi ) {

      instead of this:

      if (isNotNull && isNotEmpty) {
      // not defined for this class

      If I ever saw your code, I would change it on the spot to this second way.

      After looking through the rest of the function and seeing that those boolean variables are only used once, I would change it to your first example. Come back in a month and look at the two examples - see which one takes longer to read and figure it (even it it's only one half second, those one-half seconds add up quickly).

      Never introduce boolean variables which are only used in one top-level statement, unless it's to make your code fit in 80 columns.

      Really, you're giving very bad advice, and I'm only responding so I won't have to deal with other people taking your example.

      In fact, I can't believe you came up with this idea from a book - I'm guessing you came up with this on your own. I ask you to please point out the book which gives this advice, so I can avoid it. Someone else already noted Code Complete which explains that using "Not" in a variable name is bad practice (as opposed to using "!"). I would also like to point out The Practice of Programming which says the same thing (don't use "Not") and also gives some advice on avoiding cutesy, pointless one-shot booleans instead of just inserting a simple English comment.

    5. Re:Favor Code Clarity Over Comments by elflord · · Score: 2
      You've still got all those temps. Better to have a separate function that tests for empty: if ( ! definedForThisUi(task.getInitializerName() )) addToTaskBar(task);

      But this isn't a very good example anyway -- the original code was perfectly clear, and better than your "fix".

    6. Re:Favor Code Clarity Over Comments by MikeTheYak · · Score: 2
      initializerName = aTask.getUiInitializerClassName();
      boolean isNotNull = initializerName != null;
      boolean isNotEmpty = ! initializerName.equals( "" );
      boolean definedForThisUi = isNotNull && isNotEmpty;
      if( definedForThisUi ) {
      ... do something ...
      }
      Wow, you'd really do this? Even with the potential null dereference in the third line? Even if the third line was made safe, it's still an extra function call you could have avoided with lazy evaluation. Personally, I think your 'bad' example flowed much better. If you really wanted to get rid of the comment, you could use

      boolean definedForThisUi = initializerName != null
      && ! initializerName.equals( "" );

      The other two booleans are specious. The what for the source is easy to decipher; programmers know what null reference and empty string checks look like. The why is what might be unclear in an uncommented version of the first example, but all the necessary information is exposed using the above line of code.

  75. Re:Worst comment I ever saw by IainHere · · Score: 2, Funny

    Top of a huge listing of nasty code: /* I don't do comments */ I knew that tears would be my only comfort in the coming days.

  76. Why software patents are bad... by wfberg · · Score: 2
    Comments should really only document those things which are not obvious to one skilled in the art. And of course endlessly duplicating comments is pointless, so stick to the novel stuff..

    Of course, if you stick to these guidelines, you're not writing comments, but patents.. So better hide those from your coworkers, otherwise they'll try to claim royalties..

    --
    SCO employee? Check out the bounty
  77. Documentation is not just comments in the code by shoppa · · Score: 2
    For any system above the tiniest complexity, there's a lot that has to be documented outside the code. Just for starters:
    • Persistent and temporary file formats
    • User interface
    • Network protocols
    • System and architectural design
    • Relationships between data elements (or objects if you think that way)
    Some of the above are addressed by UML and associated tools, but for things like network protocols the RFC-type format is the hands-down winner. A particular implementation of a good idea in code might last a couple of years, but the protocols for a truly revolutionary idea will live for decades. (Look at Mosaic and HTTP/HTML for a good recent example.)
  78. The best comments are the code itself by chrysalis · · Score: 2

    IMHO, comments are often confusing. A source code that has plenty of comments becomes unreadable. And comments aren't always in sync with the code when changes are made.

    A source code with no comment, but whoose structure is very simple is way easier to understand. When the compiler sees long and overcomplicated expressions, it painfully transforms them into more, but basic expressions. So why not write simple code?

    I often see complicated lines with plenty of ternary operator usage. Why? Write the same code with simple 'if' statements. The generated code will be exactly the same, but the source code will be easy to understand.

    Another very confusing thing (IMHO) is the usage of expressions without explicit braces in loops and conditional statements. Ie. things like :

    if (ready())
    while (*++take)
    if (*take == 4)
    foo();

    Without indentation, it's very confusing. Worse : what if I want to add an 'else' here? If I want to add an 'else' to the second if, I really have to properly indent it to avoid confusion. If I want to add an 'else' to the first if, I have to add braces. This sort of thing doesn't ease the usage of macros and can give very nasty bugs when cutting/pasting blocks without carefully understanding where implicit braces are. So why not simply write :

    if (ready() != 0) {
    while (*++take != 0) {
    if (*take == 4) {
    foo();
    }
    }
    }

    The generated code will be exacly the same, but there's no possible confusion here.

    Also, 'goto' is not bad. Really. When you have to break from several loops, or just to avoid deep nesting of statements, a well placed 'goto end' is way clearer and faster than useless functions and silly 'flag_to_see_if_we_have_to_exit' variables. Don't forget that after compilation, any program will have 70% of goto-like assembler opcodes.

    Comments can be interesting to note bugs, or TODO stuff.

    Also have a look at the style(9) adopted by the OpenBSD team. There are good ideas.

    --
    {{.sig}}
    1. Re:The best comments are the code itself by scrytch · · Score: 2

      If I want to add an 'else' to the first if, I have to add braces.

      Unless you're using python, which won't even let you. In a language with braces, I can at least hilight the block and let the editor reformat it.

      Also, 'goto' is not bad. Really. When you have to break from several loops, or just to avoid deep nesting of statements, a well placed 'goto end' is way clearer and faster than useless functions and silly 'flag_to_see_if_we_have_to_exit' variables.

      When 'goto' is simply used to jump out to some label that's right at the end of a loop, that's one thing. It's usually far better to use 'return' and inline statements. If the exit was caused by an exceptional condition, you should be using structured exception handling, though C lacks it entirely (it's not too hard to add it with macros, check the LambdaMOO source code for an example) and C++'s implementation is badly botched (threw from a destructor? hello segfault.) Never said C made for very maintainable code.

      Don't forget that after compilation, any program will have 70% of goto-like assembler opcodes.

      By that logic, why not just program in asm? You had to know you were going to get called on that one.

      --
      I've finally had it: until slashdot gets article moderation, I am not coming back.
  79. Re:type* var is evil by tal197 · · Score: 2
    I would argue that int *foo means foo dereferenced is a segfault unless you've assigned a meaningful value to the pointer foo.

    We only care about the type of *foo, not its value. We can talk about the type of *foo even if foo doesn't point to a valid address, just as we can do sizeof(*foo) without causing a segfault.

    • The type of *foo is char.
    • Stack space is allocated for foo (not *foo). It wouldn't make sense to allocate space for the thing pointed to.

    You could argue that it's confusing to specify the type of one thing and the storage of another, but this model has the advantage that it actually gives the correct answer. Unlike 'char* foo, bar', which the other model fails to cope with.

  80. Hungarian Notation - God No! by smartin · · Score: 2

    There is no easier way to make code ugly and unreadable than to use hungarian notiation. nCount is not in anyway more readable that cnt, it clutters the code and is very annoying. If your code really needs to encode the data type in the variable name then there is something horribly wrong with it.

    --
    The difference between Canada and the USA is that in Canada healthcare is a right and gun ownership is a privilege.
    1. Re:Hungarian Notation - God No! by UnknownSoldier · · Score: 2

      > There is no easier way to make code ugly and unreadable than to use hungarian notiation.

      Using tradional HN I agree. See my above post for how I use a variation which I find usefull.

      > nCount is not in anyway more readable that cnt,

      Those are both bad examples. I don't like playing the guess-which-vowel-or-letters-I-left-out-of-the-var iable game. It's a waste of another programmers time.

      nCount is redundant. Count doesn't tell you anything about the variable.

      NumPlayers, MaxPlayers are much better descriptive examples.

  81. Re:Variable Names by Darren+Winsper · · Score: 2

    One of my web sites uses a Javascript function called isCrappyBrowser(). It does exactly as the name implies, returns true if the user's using a crappy browser :)

    Of course, what is crappy browser is up for debate, but it's easy to add or remove browsers from the list.

  82. Remember, comments don't have to make sense by lightspawn · · Score: 2
    Sometimes there's a certain... feeling... that you want to convey to the reader, that would make it so much easier to understand the code but cannot be expressed in words. I always use nonsense words, with a tone and rhythm carefully designed to put the reader in the right frame of mind.


    Sure, some of your stuffy cow-orkers may challenge this practice, but it's all for a good cause.

    1. Re:Remember, comments don't have to make sense by lightspawn · · Score: 2
      Enlightenment, son, sometimes may be found outside of words. Why is a mantra needed? Why can becoming one with the universe not be reached by following a recipe? Why did Tolkien feel the need to create a language for the elves?


      Remember the zen mu, or your own discipline's foo.


      Really, some people have no idea about semantic or phonetic fields.

  83. Re:Describe your design decisions and thought proc by chrysalis · · Score: 2

    If you define structure with public stuff but default, why the hell are you using 'class'? Use 'struct'. The only difference between 'class' and 'struct' is that 'class' has private members by default, while 'struct' has them public by default.

    --
    {{.sig}}
  84. Re:Comments are evil. by Anonymous+Brave+Guy · · Score: 3, Insightful
    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.

    --
    If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
  85. input output specs by yzquxnet · · Score: 2

    I get peeved at how many people leave out this critical information. Lets say they have a small section of code that is changing information in a database on the fly as it is displayed to a client. They will comment that the code changes the value but nothing else. Oh how I cringe. Not to mention people who don't comment changes they made.

  86. Rational Rose by Kraft · · Score: 2

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

    Any particular reason you didn't use Rose, that you want to share? I am just getting aquianted with Rose now, and I am pretty enthusiastic.

    --

    -Kraft
    Live and let live
    1. Re:Rational Rose by J.Random+Hacker · · Score: 2

      My WORD! The useless *BONDAGE*! There is a serious disconnect between UML models and C++ code that makes reverse engineering an impossible task for all but the simplest data models. The problem boils down to the fact that a UML relationship type can be implemented in a number of different ways. Similarly, a particular construct in C++ can represent several different UML relationship types. This leads to a many-to-many mapping of C++ coding constructs onto UML relationships.

      I also had a tough time getting Rose to generate a reasonable skeleton when using STL containers. It never seemed to construct the proper container declaration, or place it in the right scope.

      Most of the code it produced would have been hopelessly ineffecient, and I could never convince the tool to change its ways. Tech support didn't understand C++ well enough to understand (a) what I was talking about, and (b) why it was a problem.

      After struggling with the tool for most of a year, *trying* to make it work, I finally ripped the code out, stripped the Rose comments, and started making real progress.

      We now use Doc++ to document the design, and that works much much better. The only thing I miss are the UML diagrams. That last statement is telling: The UML diagrams did a great job of describing complex data structures (of which we have several), but the tool could not generate code to implement the UML diagram that was reasonable.

      I hope you have better luck, but I'd be prepared for much disappointment, unless your project is a small one.

    2. Re:Rational Rose by emag · · Score: 2

      Let me start with a disclaimer that it's been about 2 years since I had to work with Rose.

      With that in mind, here's what I found out about using Rational Rose on a unix platform:

      Rose is not a native unix app. It was ported from Windows using a commercial API kit to allow the Windows API calls to stay as they were. This caused startup to be incredibly so, even on fairly heavy (at the time) hardware with a single user on the box. And usually a couple times a month, something would cause the datafiles for this toolkit to self-corrupt, requiring the removal of a .subdir in order to even launch Rose again (and losing a lot of customizations).

      Opening up a Rose "petal" file, and then saving it, results in changes to the data, even if you didn't even touch the layouts. This was especially a pain in the ass when you'd open a file to look at a diagram, close it, then do a cvs update. Conflicts galore. If you didn't have everything stored in separate files, like, if you had a bunch of related diagrams stored in one petal file (not to mention it sounds like you're saying pedophile all the time), you were royally fucked if you went and updated a portion after someone had checked in a new version of the file (and didn't touch the area you were working in).

      It's unstable. Incredibly unstable. Like I said, it's basically a recompiled Windows app. So bus errors, seg faults, etc., were common after using it for more than about a half hour. Some of our folks never learned the "save early, save often" approach when using Rose (which was another adventure if your diagrams had any complexity), but I did after losing a few hours' work the first few times I used it.

      As other replies have said, the C++ code generation is pure crap. If Rose decided to do something one way, you were forced to write code to do it that way, even if you knew there'd be an implementation problem. And no STL support.

      In generated code, you had to be DAMNED sure that you only filled in the skeletons between Rose's "begin" and "end" comment blocks, or it would silently throw away all the code you'd written. Since we weren't using code generation ourselves, I discovered this talking to coworkers on another project who were forced to generate all of their class skeletons within Rose.

      Mixing C and C++ was a bit of a chore, too. We had some custom hardware we needed to interface with, and there was no easy way to designate the design of this portion of the code within Rose. That could just be the overall unfamiliarity we had with the product though.

      That's about all I can remember right now. I've tried to forget the whole sordid affair. Not that I'm soured on UML itself, but just Rational's products.

      --
      "The urge to save humanity is almost always a false front for the urge to rule." --H.L. Mencken
  87. Re:type* var is evil by Anonymous+Brave+Guy · · Score: 2
    You missed my point entirely. *foo is not a character.

    That's clutching at straws. You may not have defined what it means yet, but the type of *foo is char.

    Saying that *foo is a character implies that you can do something like *foo = 'A';. Which, surprising as it may seem, you can't.

    As opposed to, say, writing

    char a;
    char b = a;

    where because a is a char, it automatically has a value that makes sense, right? Oh. Oops. :-(

    --
    If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
  88. The common Joke by msheppard · · Score: 2

    /* This was hard to write, it should be hard to understand */

    M@

    --
    Krispy Cream is people
  89. Re:type* var is evil by Anonymous+Brave+Guy · · Score: 2
    OTOH, char* foo is arguably more logical than char *foo.

    Not at all. According to the grammar of C and C++, char *foo is the natural form of the declaration. According to the interpretation of others here, that *foo has type char, this also makes sense. The char* foo form is horrible, because it encourages you to think that char* foo, bar would be two pointers-to-char.

    Why is everyone here ignoring the analogous C++ case of references, where char &x does not imply that &x is a char, though? That sinks the most popular argument here for using *foo. The sounder argument is based simply on the grammar of the languages.

    --
    If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
  90. C++-specific stuff by Permission+Denied · · Score: 2
    You mention you work with C++; here are my thoughts on this language:

    First of all, keep your comments confined mostly to your header files. That is,

    // foo.h
    struct Foo
    {
    Foo();
    void bar(double x);
    };

    // foo.cc

    // calculates the square root of X using Newton's
    // method and subsequently uses this to invoke ...
    // throws: SomeStupidException
    void Foo::bar(double x)
    {
    ...
    }

    This is very bad. The comment above Foo::bar belongs in foo.h, not foo.cc. I should never have to read your .cc/.cpp/.cp files in order to use them. The comments in foo.cc should only explain clever tricks, workarounds, etc. There are two purposes for comments: (1) defining interfaces to reuse some code later and (2) describing unusual or unexpected ways of doing things. (1) belongs only in header files. (2) belongs mostly in .cc files, but can also go in headers if there's something particularly nasty afoot. This makes it easy to look at a particular project and get a good idea of how things interact, without worrying about details.

    I work more with C than with C++, but the exact same rule applies (which is not always true - there is no such language as "C/C++" and what is idiomatic for one is completely awkward in the other). Modern idiomatic C dictates that you separate your code into "modules" with a .h and a .c file for each "module." .c files should only be found alone if they don't export any functions that are used in another .c file (eg, they only "use" modules rather than implement anything). The distinction should be made explicit by declaring module-local functions as 'static'

    Another thing I find quite useful is using the "MVC" paradigm (Model, View, Controller). A concrete example: any web-based database application, like slashdot, for instance. The "Model" part is the actual database schemas. The "Interface" part generates HTML. The "Controller" part is the only part that actually constructs any SQL statements. Your controller has good APIs if you can completely change your database schemas without changing any code in the "Interface" part. Generally, well-designed systems like this require comments to define the "Controller" APIs, and don't have too many comments elsewhere.

    Someone else has already mentioned The Practice of Programming and I'd like to chime in that this is an excellent book.

  91. Re:Variable Names by Anonymous Coward · · Score: 2, Funny

    I've seen some of these in real world code, and they're not too annoying (unless you're trying to figure out what the code does :-).

    One of my favorites was a temporary function pointer named funcSoulBrotherInDaHouseNow. The same guy made a function named BashTheProcessor() with the comment //Shareef don't like it!. Another programmer named a miscellaneous callback YouWantFriesWithThat(). I was guilty of leaving around the comment // printf -- output function of kings for no reason whatsoever.

    None of these symbols are exported, so the world at large was spared until now.

    Staying anonymous to protect the identity of my coworkers. :-)

  92. Re:Peer review by mgarraha · · Score: 2

    The best way to ensure readability is to test readability. Show your code to two other programmers; whenever they have a question, revise the code to include the answer. After you make this a regular practice, you may find yourself anticipating reviewer comments as you code. Then you will understand readability in a way that no lone-wolf pundit possibly can.

  93. Well-commented code by beth_linker · · Score: 2

    You know that your code is well-commented when the moderators give it a +5 Informative.

  94. Names by Art_XIV · · Score: 2

    IMO, the most useful and frequently overlooked element in documenting code is:

    Meaningful variable/function/method/class names!

    So many developers are satisfied with instance names like the ubiquitous "temp" rather than more meaningful ones like "jobStagingList".

    Well-chosen and expressive variable names go a long way towards making code self-documenting.

    --
    The only thing that we learn from history is that nobody learns anything from history.
  95. Code Dictatorship of the Proletariat by mgarraha · · Score: 2

    I believe peer pressure is the most effective way to improve code readability within a programming team. Coding standards can only address low-level issues, and only if they are enforced. Regular peer review focuses everyone's attention on true readability issues. A senior programmer can learn a lot from a junior programmer this way.

  96. Because... by Greyfox · · Score: 2
    Nothing makes a maintenance programmer want to slit his wrists faster than Hungarian Notation. Most of my work has been maintenance programming and by some very odd coincidence I've never seen code written by someone who knew how to program using Hungarian Notation. Every time Hungarian Notation was involved, the programmer was such a piss poor coder that it was generally better just to completely scrap their code and start from scratch. As far as I can tell, the programmers involved were using Hungarian Notation to reassure themselves that they knew how to program because they were using a "methodology" when in fact they were absolute fucking idiots who were just wasting the air we breathe. Perhaps not so coincidentally it was also the Microsoft coding standard a few years back. That explains rather a lot doesn't it?

    Now I'm not saying that all programmers who use HN are idiots. This is just in my experience, which is a relatively small cross section of a much greater pool of code. Seeing the style does set an expectation with me now, though, since all my experiences thus far have been bad. Perhaps one day I'll be pleasantly surprised.

    Hmm... asking about opinions on HN might make a good interview question (on either side of the table) now that I think about it. I'll have to add that to my list of questions for when they ask "Do you have any questions?"

    --

    I'm trying to teach myself to set people on fire with my mind... Is it hot in here?

    1. Re:Because... by jeremyp · · Score: 2

      When I'm programming for myself (not following somebody else's programming standards) I sometimes add a suffix to give me a clue about the name e.g _t for a type as opposed to a variable or _p as an abbreviation e.g. instead of "PointerToSomeData" I'll use "SomeData_p".

      OTOH I think Hungarian notation sucks. The main reason being that it is at the front of the variable name. I'm a firm believer in putting the important stuff at the front, which is what the variable is for. The M$ dev environment has a class browser and there is nothing more irritating than to see a nicely alphabetical list corrupted by the fact that everything begins with lpsz or m_.

      --
      All I want is a secure system where it's easy to do anything I want. Is that too much to ask ~~ Randall Munroe
    2. Re:Because... by catfood · · Score: 2
      Nothing makes a maintenance programmer want to slit his wrists faster than Hungarian Notation.

      Unless.

      Your programming language has such weak typing that you have to use it to keep things straight. e.g., Clipper--it lets you declare variables but not their types.

      LOCAL sCustomerID
      is about the best approximation you'd get to what C++ would call
      std::string customer_id
      so at least there's an argument for keeping a Hungarian-style type prefix.

      If the compiler won't enforce type safety, a convention such as Hungarian might help.

    3. Re:Because... by Amazing+Quantum+Man · · Score: 2

      The one hungarian style habit that I picked up (from when I did VC for a living), and sort of still maintain is distinguishing class members from globals (and yes, I know I should use "::").

      I tend to have class members be m_this_member, but that's the only hungarian I still use.

      --
      Fascism starts when the efficiency of the government becomes more important than the rights of the people.
  97. Andersen Consulting: Kludge by hughk · · Score: 2

    At one stage I had to do a quick and dirty with some software that was hitting priority inversion problems. I was working AC who had caused the issue by sloppy coding - I commented the fix with a warning that this was a "Kludge" and needed a proper cleanup later. AC petitioned for and got the "Kludge" word removed.

    --
    See my journal, I write things there
  98. Re:Braces by himi · · Score: 2

    Go read K&R on this.

    And use 8 space tabs - that makes code blocks more obvious than anything else, and it even warns you when you're getting ridiculously deeply nested control structures.

    Another good thing to read is the Linux kernel coding style documentation (Documentation/CodingStyle). It's a good discussion of a lot of this stuff.

    himi

    --

    My very own DeCSS mirror.
  99. Another great book by KFury · · Score: 2

    For advice on commenting, as well as so many other issues that differentiate a journeyman software engineer from a master, I highly recommend The Pragmatic Programmer. When I start a new job, I often wish my coworkers had read it, and by the time I leave the job, I try and make sure that as many as possible have.

    All right, I know that sounds like a commercial, but it's really a great book.

  100. Re:Variable Names by jeremyp · · Score: 3, Insightful

    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.

    --
    All I want is a secure system where it's easy to do anything I want. Is that too much to ask ~~ Randall Munroe
  101. Re:Variable Names by SecurityGuy · · Score: 3, Funny

    Bah, he was hard to work with, he was easy to terminate.

  102. Re:Comments are evil. by SecurityGuy · · Score: 2
    There is no good resource on why it is, because it isn't. :P


    I say this for one simple reason. The code tells me what you actually did. It doesn't tell me what you intended to do. Auditing someone elses code is a royal PITA when they haven't bothered to tell you what a function is supposed to be doing.

  103. Memories!!... by Hoi+Polloi · · Score: 2

    Beagle Bros! *eyes tearing* I remember those halcyon days! So innocent...so much in so little RAM.

    --
    It is by the juice of the coffee bean that thoughts acquire speed, the teeth acquire stains. The stains become a warning
  104. Re:type* var is evil by himi · · Score: 2

    Ummmm . . . No, the type of *foo in char *foo; is a char, and foo is a pointer to a char. There's no notion of forcing anything here - you're /declaring/ the variable, not dereferencing it.

    In any case, even when you /are/ actually dereferencing, unless you explicitly cast the variable to a different type somewhere along the line the compiler will pick up the mismatched type error. Since C isn't strongly typed, this often gets you a warning and nothing else, but that reflects the fact that C lets you treat a chunk of memory however you want, because it was designed as an OS implementation language where you need direct manipulation of memory. But the language itself /does/ have a strong notion of the type of variables - strong enough that you can do a lot of static analysis. It breaks down around pointers and typecasts because you can throw away information if you choose, but again, the language's notion of types is well defined, with loopholes that make playing games with memory easier.

    I could compile C to Caml (a strongly typed language) if I wanted to, and the only difficult bit would be providing generalised typecasts (Caml doesn't allow casting in the general case, only for things like ints to floats or chars to ints, where there are clear, well defined conversions). Most of the type handling would pass straight through untouched.

    Don't make the mistake of looking at the runtime behaviour of a language and thinking that defines it's semantics. In this case, a construct that's entirely meaningful will cause a runtime error if some other stuff isn't done, but that doesn't change the fact that it /is/ meaningful, and that the language properly defines that meaning.

    himi

    --

    My very own DeCSS mirror.
  105. This will lose you points at CMU... by Lethyos · · Score: 2
    Had a friend who I worked with at a start up one summer. Told me - quit frustratedly - that he lost points on an assignment for this...
    // increments i by one
    i++;
    Don't do that. Some code is self-documenting. Document pre and post conditions of complex procedures, and make notes of what they do internally. As for the algorithms described in those procedures, leave that for external documentation. (They often require proofs anyway which do not fall into the scope of source documentation.)
    --
    Why bother.
  106. Why, not what by andy@petdance.com · · Score: 2
    The rule to creating comments is simple:

    Explain WHY the code works as it does, not WHAT it does.

    Anybody can tell what it's doing. The reasons behind the design are another matter entirely. Here are some examples.

    # This code doesn't use URI::URL because URI::URL
    # doesn't handle foo:// URLs, at least as of
    # version 1.1.4.

    # This goofy switch statement is called
    # Duff's Device, and it speeds up the loop about
    # 15-20% under load. See p. 182 of "Writing
    # Efficient Programs" by Jon Bentley for more.

    # Using the DB this way is a performance hit,
    # but it's the only way we can be sure that we
    # don't have a conflict in the detail records.

    # Normally, we'd display magic-button-animated.gif
    # here, but Marketing hasn't given us the updated
    # version yet (as of 5/20/2002), so we have to
    # use magic-button-static.gif instead.

    And a real-life example that I pulled from our code:

    my $delve_link_image = "";
    # XXX The interface fashion of the week dictates removing the image
    # link. I'm leaving the code for now in
    # case fashions change again. -- mmh 020515
    #my $delve_link_image = (old code)

    Just make sure that coders know that their comments are to be factual, not emotional. Comments like "I'm doing it this way because Bob said I had to" are useless at best, and inflammatory at worst.
  107. Code Review by tarsi210 · · Score: 2

    Code Reviews - We love them, we hate them, but they work WONDERS. To have another programmer read over your code and have to try to figure it out is absolutely invaluable. Besides finding really obvious bugs or questionable places, your commentary can be critiqued as well.

    For those of you that program by yourself, do the "let-it-ferment" thing. Write some code, then stick it at the bottom of your stack and pull it out in a week. If the comments and code still make easy reading and good sense, keep it. Otherwise, assume if you can't read it in a week, no one else will be able to read it the first time, either.

    In an actual programming dept., if you're the manager/boss, make a set time each week to review code by other members and stick to it. Your programmers may complain but they'll complain worse if they have to be there till 2am fixing a really dumb mistake.

  108. Brooks! by mikeee · · Score: 2

    Very true.

    In _The Mythical Man Month_, Brooks wrote (paraphrasing here): Comment your code and I will remain confused; comment your data structures and your code will become obvious.

  109. Re:Things to bear in mind (Tips With Editors!) by LF11 · · Score: 2, Informative

    I use Vim primarily, and I'm beginning to switch to using Emacs for coding.

    Vim has the most wonderful autocomplete hotkeys; type the beginning of the function/variable name, then press Ctrl-p to search up and Ctrl-n to search down through the file, buffers, etc. Now, long variable names are actually usable for 80wpm typists like me. (I'm around 40-50 for plain text).

    Does anyone know what the equivalent (or at least sorta-equivalent) commands are in Emacs?

    -Chris

  110. favorites... by mikeee · · Score: 2

    My favorite was actually an error message; a piece of (commercial!) software crashed, with the error message:

    "Dave says this case can't happen."

  111. Re:Variable Names by Pig+Hogger · · Score: 2
    ...
    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.
    ...
    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.
    Lemme guess. Those clients were civil/mechanical engineers, right?
  112. Re:Variable Names by Paranoid · · Score: 2

    Actually, as a part-time sysadmin, most-time coder, I agree.

    The point of this whole thread is to understand what the code does, right? If your code is unclear, you can aid people in reading it through comments and variable names, but if your code structure is easy to understand, then the goal has already been achieved!

    Sure, it can be difficult to decide without bias how understandable your code is. Never overestimate the intelligence of the person who will maintain your code. However, to me, thats simply thats another argument for keeping your code structure clear to begin with.

    --
    Paranoid
    Bwaahahahahaa.
  113. "Why" not "what" by Mr.+Fred+Smoothie · · Score: 2
    I personally believe that code should be as self-documenting as possible; the "what" of what the code does should be explained to the extent practical by the variable, argument, function and method names (i.e. getAccountActivityForDisplay(const char *account, date_range from_to, account_formatter fmt)) and code structure.

    In comments, I think it's most helpful to explain the "why's" of the code, (i.e. :

    SomeClass someObj = null;
    try{
    someObj = someFactoryMethod(someInput1);
    }
    catch(SomeExpectedException expected)
    {
    // log but do nothing, conditional block will
    // handle this along with related problem 2
    LogMgr.logWarning(expected );
    }
    catch(Exception unexpected)
    {
    LogMgr.logError(unexpected );
    // don't show the user our stack traces
    rethrowUserSanitizedError( "User-sanitized message");
    }

    if(someObj == null || !someObj2.someCondition(someInput2))
    {
    showInvalidInputMessage(so meInput1, someInput2)
    }

    I think this helps prevent another programmer's incomplete understanding of the "what" causing them to overlook consequences of making code changes.

    --

  114. My list by edp · · Score: 4, Interesting

    One purpose of comments is to explain the code to another engineer (including oneself in the future). Another purpose is to demonstrate the code works, whether an informal argument that the code does what it should or a mathematical proof. These two purposes have different needs.

    For the former case, standard writing rules apply. Decide who the audience is. I often figure the audience is an engineer who knows the type of programming at hand, but doesn't know what is done by this particular code, and may or may not be familiar with the product, depending on circumstances. Knowing the audience tells you what assumptions to make and what has to be explained, either by prose or by giving directions to reference material.

    Write complete, grammatically correct sentences. This goes a long way to making comments comprehensible. Sometimes a little phrase won't be understood because the reader can't fill in the unwritten parts, or because there's ambiguity in the wording. It is okay to use short phrases when describing objects being defined or declared (e.g., "number of links to this object" or "dollars owed this customer), but keep the context in mind. Introduce the compound object with sentences where appropriate.

    "Dollars owed this customer" reminds me -- use units. Don't write "Money owed this customer" or "time since last update." Specify seconds or milliseconds, not time. Document how the object models whatever it is modeling. That may be a physical thing like time or a conceptual thing. E.g., if a pointer connects one object to another, document the relationship that represents. If a "debt" class contains a pointer to a "person," don't document it as "person associated with this class." Document the relationship -- this particular pointer may represent the debtor, the creditor, the escrow agent, or somebody else.

    Give context. I have seen thousands of modules that just leap into code with no explanation of what they are. Even if the comments say what a function does, a reader might not really understand it until they know what it is used for. Document where the code fits into the bigger scheme and what it is used for. Give the reader context so the purpose of the function makes sense. Even if a complete mathematical description of a function is given, so that the reader can precisely predict its behavior in every situation, it might not make sense to the human mind until they have a mental image or model of it.

    For the second purpose, demonstrating the code works, explain how the code implements an algorithm. It's not enough to explain what the steps are doing; you need to show how the total result comes out of the algorithm, unless it is something simple or familiar. E.g., a formal description of the long division taught in elementary school would generally be incomprehensible. "Find the largest digit d such that d times q is less than r[i]. Subtract d*q from r[i] to get r[i+1]. Append d to output..." Nobody seeing that for the first time would understand what it is doing, even if all the steps were clear. Even if you explained each step and explained the result, it won't be clear to some readers how the steps produce the result, so explain that.

    Document alternatives that weren't chosen, and the reasons why. If you were tempted to implement algorithm X but found you had to do Y because some error might occur, record that information. Otherwise, somebody working on the code next year might see your longer code for Y and change it to X without realizing the problem.

    This isn't intended to be a complete list, just what occurred to me at the moment.

  115. Self-documenting code needs little comment by werdna · · Score: 2

    Code should, so far as possible in context and langauge, be self-documenting, which is to say: the code by itself should lead me as far as it can in understanding. Good, well-designed OODLs make this somewhat easier than more traditional straigh-line imperative languages, but all high-level programming languages are capable of such practices.

    This means coding standards -- all code doing substantially the same thing should probably look the same. Indentation style should be sound and consistent, and unless strong countervailing arguments exist, all procedures should be very short, very well-named, and be very straightforward. As others have noted, variable names should be as precise and accurate as possible -- and, believe it or not, naming variables and procedures properly all the time is VERY hard.

    When code gets written, and you start smelling the "smells" of imperfect code, this means it is time to refactor: move variables out of objects to where they belong; collapse classes where appropriate, or break them up where appropriate; rename procedures. break procedures up to clarify (and rename), consolidate procedures to clarify (and rename) and so forth.

    An excellent book on refactoring is "Refactoring" by Fowler. Refactor until you shouldn't refactor any more. Then the code, sans smells, should read like a charm.

    Then, and only then, will you know what the comments need to say. Comments should be things not possible to express in the code per se, or which couldn't reasonably be understood without deeper analysis. For good, well-factored and self-documenting code, most comments are usually tight, short, rare and VERY helpful. Indeed, most comments in good well-factored code are usually unnecessary for experienced readers -- and too many comments actually get in the way of reading the code.

    One last thing -- keep your code comments current. Too often, changes are made in code without countervailing updates in the comments (since compilers tend not to pick up such things. The single worst possible thing is a comment that is wrong. Worse than not commenting at all. And both are heinous. Almost as bad is commenting superfluously or too much.

    My view -- write your code right. Then, the comments, when necessary, will be apparent -- kinda' like the code became apparent from writing right.

  116. Re:Variable Names by jdavidb · · Score: 2

    I do that too!

    • $ - scalar
    • @ - array
    • % - hash
    • & - function

    and so on. Oh, wait. :)

  117. It's sophomores like you... by Pollux · · Score: 5, Informative

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

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

    1. Re:It's sophomores like you... by Darth_Burrito · · Score: 2

      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.

      Not necessarily true, I have seen examples of the above where the coder actually went on to make comments regarding his choice of variable names. He ended up going on about a rant involving low self esteem.

    2. Re:It's sophomores like you... by ahde · · Score: 2

      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.

      Congratulations, you've just described a function header. The only reason to include that kind of info in comments is if you are using some automatic documentation tool like javadoc--which is a *very* good reason, but a waste of time and space otherwise.

      Overall, you're better spending 10 minutes deciding on accurate, descriptive function and variable names are than 5 minutes duplicating your header in pseudocode or filling the page with descriptive comments.

      Any complex algorithm (like creating a hash table) is not going to be able to be debugged from reading the comments anyway.

  118. Knuth - Literate Programming by goodviking · · Score: 3, Insightful

    Some variation of the methods described in "Literate Programming" by Donald Knuth 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 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).

  119. Sometimes they just dont grok it. by crovira · · Score: 2

    I once wrote some code in Command level CICS-COBOL that used GETMAIN and FREEMAIN to do dynamic memory allocation so I could take a data structure in a file (by order.item.warehouse.quantity,) and stand it on its ear (by warehouse.order.item.quantity,) to get at the data that way.

    It worked fine and I documented it and the BLL cell layouts properly but the CONCEPT of dynamic memory allocation proved to be the stumbling block.

    I ended up giving a course on my hack and they still didn't get it. I eventually left the company and left them with working code that they were not intellectually capable of modifying. I didn't feel good about that.

    Sometimes they don't understand one concept (object instance relationships) and sometimes its another (state machines) but I always seem to encounter people having problems that they are too busy struggling with to see that the problem lies with their application of an innapropriate solution.

    AND THEY AREN'T MENTALLY EQUIPPED TO PERCEIVE THE TRUE DIMENSION OF THE PROBLEM. (Not its metric, [I didn't say SCALE of the problem,] but its topology.)

    There is bugger all to be done in those cases.

    Being ignorant of the uses and applicability of state machines leads to combinatorial explosion of GUI (and supporting objects) code to handle different state transitions.

    Rather than maintaining the state machines, (not even the engines but the state transition arcs and nodes,) they were ending up replicating GUI code.

    That was really fucked up. I was asked to resign. I did, heaving sighs of relief.

    (And then somebody used the building as a landing strip. Yeah. I'm still fucked up about that...)

    --
    MSBPodcast.com The opinions expressed here are my own. If you don't like 'em... Think up your own stuff.
  120. They'll always complain.... by pjrc · · Score: 2
    Well, they'll almost always complain that your code "isn't commented enough", when they are forced to read through it and learn enough to make some changes.

    One of the best examples from my personal experience is a fairly large 8-bit assembly language project I did (for an embedded PIC16C76-based product). The project has approx 25000 lines of assembly code distributed in about two dozen files (which built about a dozen different flavors of the product, though virtually no code was duplicated due to common code being used by includes... it really was about 25k lines of assembly!)

    The first time another programmer worked on it, he of course complained that it wasn't commented very well and lacked documentation.

    In fact, a quick grep ';' *.src | wc compared to a wc of all the files revealed that 34% of the lines had a comment (the vast majority the whole line was a comment, as I tend to write blocks of prose above sections to explain what they do, rather than a comment for each register move).

    But if 8500 lines of comments wasn't enough, there was an 11-page document I wrote about the design of this firmware... about half of it was a "roadmap" that described the "larger picture" of the firmware and how it was arranged into the various files. The other half documented specific tricks (like a 6-instruction sequence including a skip-past-a-skip that achieves a 16 bit add/subtract in that PIC part which lacks carry input). There was also a lengthy discussion of the overall strategy for managing the various bank-swapped memory of that processor and some other stuff about the real-time performance (that was a hard real time application).

    Learning is painful for most people, and learning someone elses code seems to be absolute agony for many engineers & programmers. They always complain that you didn't document/comment the code enough, even in an extreem case like this!

  121. Happy medium by davebooth · · Score: 2

    Lots of posts on quantity of comments and theres a bundle of good arguments for both the more-is-better folks and the dont-overcomment advocates. Similarly the drive to make your variable names meaningful is worthwhile but the one addition to any code, be it perl, C or anything else, that makes maintaining it easier has to be the humble newline.

    The important thing is not how many comments of what type but the overall layout of the source so that it is consistently understandable on reading through it. If a comment is required to accomplish that then insert one. If, OTOH, all you need to do is break up and indent the lines a bit more intuitively then do that rather than trying to explain the more awkward structure in a comment.

    Sure, you can easily pack a fully functional perl script into a 4-line .sig if you want but a 100 line script thats as squeezed together as it possibly can be becomes unreadable no matter how many comments are inserted into it. If a single line of code does more than one step in your program then consider breaking it up. If it absolutely has to be one line in order to work then backslashes are your friend. The guy that reads your code to find out how you did that after you've moved on to bigger and better things might be an entry-level hire who has enough of a learning curve to cope with without wrapping his/her head around tightly compacted code as well.

    Remember how simple you kept it when you first started learning a language? Keep it that way when you're more experienced unless theres a reason to do otherwise.

    --
    I had a .sig once. It got boring.
  122. Experience, Comments, and Design Patterns by Bouncings · · Score: 2

    I've noticed that the exerience of the programmer, like most aspects of software design, is only an asset if the programmer has done a variety of tasks. I've seen veteran programmers who have only written code and actually never maintained it. They never actually learn what maintainers need to make modifications, so the comments only help them write the code.

    My best advice is to do as many tasks in the software development process as possible. This includes testing, maintaining, and working with users and even technical support (gasp!). Don't get stuck doing one thing. You won't get better and better at it, you'll become more out of touch and therefor do an even worse job.

    Experience is best measured in deversity, not years.

    --
    -- Ken Kinder ken@_nospam_kenkinder.com http://kenkinder.com/
  123. Re:Describe your design decisions and thought proc by scrytch · · Score: 2

    If you define structure with public stuff but default, why the hell are you using 'class'? Use 'struct'. The only difference between 'class' and 'struct' is that 'class' has private members by default, while 'struct' has them public by default.

    Why should he? He's not writing C. Why should he have to double the syntax when, as you said, 'class' would do the exact same thing? Maybe it's better that he explicitly has to make everything public. Maybe he thinks, as do programmers in most other languages that support classes and struct, of structs as being mere aggregated data and classes being actual object definitions. Or maybe he just likes browsing through classes by searching for "class " in his editor. Just because the language supports something doesn't mean he has to do it, especially when it actually reduces the value of the code.

    --
    I've finally had it: until slashdot gets article moderation, I am not coming back.
  124. Re:type* var is evil by markmoss · · Score: 2

    Robert Pirsig in Zen and the Art of Motorcycle Maintenance commented on how as a tech writer assigned to write user manuals, usually the guy assigned to teach him how the thing worked was the least competent and knowledgeable on the whole team. Nobody minded _him_ being taken away from his work to do documentation....

    I suspect coding or documentation standards are often the victim of this same practice, squared.

  125. They MUST vs. they WON'T by Mr.+Fred+Smoothie · · Score: 3, Insightful
    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.

    --

    1. Re:They MUST vs. they WON'T by ahde · · Score: 2

      More like teaching condoms as a method for avoiding pregnancy. It's an extra hassle. Sometimes you don't feel like it, sometimes you don't have time, and sometimes it just doesn't work right.

  126. Primary audience of code is other programmers by p3d0 · · Score: 2
    Just like any writing, the author of code has an audience in mind. Too often, this audience is the computer or compiler. However, the compiler will be able to handle just about anything you throw at it--see the obfuscated C contest for evidence of this--so to consider only the compiler will leave all other audiences (including yourself in a few months' time) in the dark.

    Think of your code as a document that describes how something is done. Always imagine that it is being read by an intelligent person who doesn't already know how or why this thing is done in a certain way.

    Oh, and never define words in terms of themselves. This is not helpful:

    int markedTreeCount; /* How many trees have been marked */
    Consider: if you saw a definition like this in a dictionary, you'd laugh out loud. Every definition should either (1) completely avoid all the words in the term being defined, or if that is too cumbersome, (2) have a reference to a document/glossary/whatever that describes those words in more detail. If your project has no such glossary, it probably needs one.
    --
    Patrick Doyle
    I mod down every jackass who puts his moderation policy in his sig. Oh, wait a sec....
    1. Re:Primary audience of code is other programmers by smallstepforman · · Score: 2

      The primary audience of code is not the compiler. Anyone SW engineer can write code which a machine can understand. A great SW engineer writes code which another human can understand. A HUMAN is your target audience.

      Quote from Martin Fowler, Refactoring.

      --
      Revolution = Evolution
  127. Make your code readable! by UncleRoger · · Score: 2

    It's simple:

    Use COBOL!

    --
    Stupid people will be persecuted to the fullest extent allowed by law.
  128. Re:Constructive comment on symbol names by Beliskner · · Score: 2
    Disagree. When reading this code, since it's sequential the former is better. The second code fragment jumps around like a Mexican jumping bean for no reason. Think about it, what you're actually doing when you reverse-engineer it is using your brain to mentally inline the actual code above.

    I do believe however that if you increase the complexity with a few if() conditional statements that the second form would be better BUT the support function declarations should be more compartmentalise by a
    /*
    SUPPORT FUNCTIONS, MAIN EXCUTION BELOW
    */

    What I HATE is unnecessary function calls that give you a 10-level deep stack trace for a simple "Hello world"

    --
    A caveman dreams of being us, the incalculable power and riches. We dream of being Q, then what?
  129. Comment the WHY or the HOW and not the WHAT by angel'o'sphere · · Score: 2

    Hm ... I find the following observation interesting:

    Most programmers (especialy those without formal education) find programming more an art than an engineering task.

    If you talk to them about a "software project" they imediatly tell you HOW to do it and skip the "analysis phase" in which you usualy try to figure WHAT is needed.

    Another thing, similar interesting is: how do you teach or how do you learn?

    The best way is to start with the WHAT. That means simple facts, like: "a programming language supports the concept of storage and the concept of instructions(usualy)".
    Supported with simple examples.

    Then you teach the HOW. How to use the concept of storage? How to use the concept of instructions?
    Supported with simple examples.

    Finaly you teach the WHY. That means you teach the principles which lead to "the physical laws", efficiency, beauty or in depths insights. E.g. why to use a guard element at the end of an array while searching the array with a loop.

    If we go building a new application for a customer we usualy do an OO analyis and a OO design. (If we are engineers and not artists)

    That means we first analyze the WHAT. What is the application supposed to do? Then we can go deeper and analyze HOW is the application supposed to do it?
    So far we are far away from code. We only found classes, some attributes and some few methods. Because we looked only on the WHAT. The HOW, we looked on so far, was only the user point of view.
    If we shift to design, to actually get closer to the code, we more and more concentrate on asking us HOW. HOW will it work, HOW can it work, HOW should/will it be implemented to work. From the domain constraints of the application we shift into technical constraints of the run time environment and the implementation.

    So .... writing program code is mentaly a thing where you fiddle with the HOW.

    How to get a new customer into the DB? The code describes how to do it ... even if the code is hard to understand.

    The first goal in coding(the foundation is layed by the analysis) is using good class names and good method names(or the equivalents if you program not oo).

    This gives you an insight WHAT you want to achive.
    While you code you fill methods and add methods(if you otherwise would write to big methods) and craft HOW to achive it.

    So, what should a comment now do? The comment is needed to fill the gap, or to express the third point of our mental model we make: WHY.

    OOPS? Yes, we know WHAT we want, we know HOW to get it, but WHY do we get it in that way?

    Comments are needed to express WHY we in certain cases drop a habit. (e.g. most for loops in C/C++/Java have for(;x less_than y;) ... if we need x == y, suddenly we should write WHY we need that)

    Several posters pointed out this is a dumb comment:
    i++; // increment i

    Right! But it is not dumb because it is obvious what i++ does, or because it is superfluvious.

    It is dumb because it explains the WHAT. It says: what the line of is code doing.

    Unfortunatly comments like that are used in language teaching books. To TEACH coders that "++" means (post-)increment.

    New coders learn by that: you have to comment like this.

    So again: don't comment the WHAT. Comment the WHY.

    In teaching OO my rule of thumb for method sizes is: it needs to fit on the screen of my lab top.

    As I beam with my labtop onto the wall, I use a big font, like 18. Methods then have a size of 8 lines or so.

    If a method gets longer, you usualy make sections and write a comment on top of that section, do you?

    Well, thats an excellent way to extract a method name from that comment and to put that section into a "protected" method.

    With having more methods, some of them protected and factored out of otherwise to big methods, we suddenly get more freedom to "modify/extend" derived classes. And: oops, we suddenly are close to use a well known design pattern: Template Method. The big method is smal and calls several small methods. The big method is the Template Method, the smaler ones are hook methods. In a derived class suddenly I can moddify such a single step of the algorithm by overwriting a hook method.

    So, now you probably have a class with 25 methods?
    Probably you should divide the class up then ...

    The art of OO Analysis gives you the insiged to realize early that a class mixes two concepts and therefor should be split up into two classes.
    E.g. keeping all attributes of an author in the book class, just lets the class explode and is wrong anyway.

    The ART OF OO PROGRAMMING is to anticipate such refactoring points and to use them wisely when appropriated(and not to use them when not).

    Programming in itself is no art. Just like painting in itself is no art. Artist usually studdy 10 years and more under the guidiance of other artists .... coders should do the same.

    My programms have nearly no comments. Except for classes, WHAT is it for. Methods and their parameters, WHAT are they for, and sometimes HOW do they work.

    If a method body is not clear, or if I feel I should do it, I explain WHY I do certain things like I do.

    Except for counters all variables have long explaining names. Methods and classes anyway.

    I do not use index variables like "bookCounter" because a loop like:
    for (int bookCounter=0; bookCounter less_than MAX; bookCounter ++) {
    if(found(book[bookCounter]))
    return book[bookCounter];
    }

    meets my criteria of: it does not give any benefit. I see WHAT is going on, and there is no special need to explain WHY something is happening.

    A simple 'i' is good enough. (I used for more than 10 years variables like bookCounter ... and dropped it some 4 or 5 years ago.)

    The hint, pointed out by several posters, to use assert() instead of comments is absolutely valid. Drawback: tools like doxygen and javadoc, do not transfer those asserts into the outside method documentation. So by browsing HTML docs you do not see it.
    If you have to dig into the code anyway, an assert is much better than a comment. Especialy if you have a test suit triggering your asserts.
    To bad, realy to bad, that SUN went for an assert facility in Java 1.4 and did not use pre- and postconditions like Eiffel :-(

    Regards,
    angel'o'sphere

    --
    Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
  130. Doc & code sync always drifts! by Mr.+Fred+Smoothie · · Score: 3, Insightful
    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.

    --

    1. Re:Doc & code sync always drifts! by Mr.+Fred+Smoothie · · Score: 2
      If you don't, your successor will have an easier time fixing the bug after you're fired.
      Programmers fired for not updating documentation? What planet do you program on? I can't even get programmers fired for writing classes with single accessor methods for accessing multiple data fields (taking the fieldname as a string, of course).
      --

    2. Re:Doc & code sync always drifts! by ahde · · Score: 2

      whoops...

      just sent out a bean with methods like:

      setParamName(param)
      setParamValue(value)
      getPa ramValue(paramname)

      All took sinlge String. And I did it to avoid introspection. Sure makes jsp easier though.

    3. Re:Doc & code sync always drifts! by Mr.+Fred+Smoothie · · Score: 2

      Um, if you want to avoid using introspection, why don't you just stop using Java Beans and access your object's methods and fields directly?

      --

  131. When I get bored... by Rorschach1 · · Score: 2

    I write all of my comments in haiku.

    comments in haiku
    not for any good reason
    i was really bored

    Ok, not a really good example, but you know what? No one's ever said anything about it.

  132. eat your veggies by _|()|\| · · Score: 2
    most people who read [books on nutrition and dieting] end up eating junk food anyway because they just don't have the time to do it right.

    I use habits learned from Code Complete every day, such as taking the time to choose a good name (no, I'm not talking about Hungarian notation). The single most important point of the book is that people read code, too.

    I found Writing Solid Code, another Microsoft Press book, to be less enjoyable. It was, however, worth its price for one C habit I've retained: put the rvalue on the left in equality tests. For example: if( 0 == foo ). Why wait until run time to find that you've accidentally assigned, instead of compared?

    As to "junk food" in programming, I prefer to categorize all of that as "rapid prototyping."

    1. Re:eat your veggies by Jaeger · · Score: 2
      Using the -Wall switch with gcc (and, I assume, dinking with the options on other compilers as well, although I don't have as much experience with them as I do with gcc) will warn you if you try to do something stupid like if(foo = 0). It's not foolproof (it suggests that you can put an extra set of parenthesis around the equality to supress the warning), but every thing you can get to help you out is a good thing.

      My all-time favorite bug that ever crept into my code was in a C++ constructor. I wrote something like

      MyClass::MyClass(int _blah) : blah(blah) {}
      instead of
      MyClass::MyClass(int _blah) : blah(_blah) {}
      Even with -Wall, gcc still didn't warn me that I was doing something that made no sense at all.
    2. Re:eat your veggies by flossie · · Score: 2
      For example: if( 0 == foo ).

      I thought that was a really great technique when I first came across it and used it extensively. However, it is shocking how disruptive this construct can be to one's train of thought when reading through a complicated algorithm. It is also of limited value as it doesn't really help when it becomes necessary to test if (foo == bar). Consequently, I have reverted to relying on the compiler to tell me when I have made a typo.

  133. Good list; a couple of observations by Spinality · · Score: 2

    This is a good framework. Your code is probably very pleasant to read. I might argue with your position about marking changes, however. There are times that it's highly useful to see why and when a particular block of code was inserted. Basically, if it's relevant to understanding or troubleshooting that chunk of logic, then by all means leave fingerprints.

    One other suggestion you didn't make was: Write the comments first. In The Old Days this was much more important, when working e.g. in assembly language, C6, or FORTRAN. But it's still very helpful. As you start writing the code, implementing your abstract design, you pass through all the major decision-points that shape the detailed implementation. It's relatively easy to capture those decisions as you rough out the module, explaining macro control and data flow, algorithm design, etc. Later comments tend to focus on the gory details rather than the big picture.

    Another suggestion is: Revise old comments. It's easy to let old comments go out of date, particularly module-level and block comments. Part of the revision discipline should be reading through the existing documentation and making sure it's (still) accurate. If not, fix it.

    Two more: Design and use a set of standards for naming, module headers, error handling, diagnostic messages, etc. These things don't evolve; they have to be implemented by choice and agreement. And Use whitespace intelligently to ensure that important things are easy to see.

    --
    -- We all have enough strength to endure the misfortunes of other people. La Rochefoucauld
    1. Re:Good list; a couple of observations by Spinality · · Score: 2

      I agree that source control is orthogonal to commenting and should be used appropriately. But rigorous source control is not available or appropriate in every context (e.g. fragmented source environments like Smalltalk, or many single-developer projects where source control becomes a barrier to productivity). And besides, I *like* seeing a comment like

      // inserted 2/24/01 to resolve race condition problem
      // I think I got it, but call Bob at x235 if you wind up looking at this code :O
      . . .
      // end of race condition fix

      As far as herding cats is concerned, I find that developers who are aghast at the idea of imposed standards may be quite willing to work collaboratively on developing those standards: "Let's come up with a set of naming conventions to help new hires get on board. And in the process, we can decide how we'd really like to do things 'right' in the future. You draft a set for local variable names; I'll draft a set for database objects; then afterwards we'll work together on shared data and class hierarchies." It's true that everybody will have strong and conflicting opinions about what standards are reasonable; but talking these issues out can often lead to a better understanding all around, since most such opinions are based on valid concerns that should be balanced in any group standard.

      My commenting discipline matured when doing operating system programming in S/370 assembler language, an environment just bulging with entropic forces trying to make code incomprehensible. My coding style became semi-famous because I was essentially always programming with the comments, inserting the actual source code to implement those comments like a human compiler. It worked well, and since I did it so much and so fast, the commenting strategy became second nature. So even though it wasn't as necessary in C or (shudder) VB or whatever, it's always been natural to code outside-in, from concepts and data structures into the details.

      A technique I often used was this: 1. Invent a pseudocode language that is close to the problem domain for describing the solution. 2. Write comments using that pseudocode to show the algorithm. 3. Either a) Insert source code that performs the logic, or b) Write a compiler/interpreter/dataflow graph/whatever to implement the pseudocode language, and transform the comments into source code or an instruction stream for that engine. (You might think of Regular Expression processing as an example of this approach.)

      The compelling reason to invest so much value in comments and other precoding scaffolding is that it encourages rearchitecting the system ('refactoring' in today's parlance) a few times during implementation -- it's relatively easy to change things and recognize the canonical elements when you're still at a conceptual level. It gets harder and harder as the details get fleshed out.

      JMHO - Trevor

      --
      -- We all have enough strength to endure the misfortunes of other people. La Rochefoucauld
  134. Re:type* var is evil by mr3038 · · Score: 2
    char* foo, bar;
    char *foo, bar;

    IMO, the syntax used to define two pointers on a single line in the C is broken. I'd guess that it's a mistake in the original spec and simply hasn't been corrected because the fix would break some code.

    Think about it, the real type is "char*" "bar" not "char" "*bar". This can be easily demonstrated with the type casting syntax: you write "(char*)(foo)" instead of (char)(*foo) -- and notice how those mean different things. I always write "char* foo;" and define only one pointer per line. I define loop counters like i, j, k, m and n on a single line, though.

    --
    _________________________
    Spelling and grammar mistakes left as an exercise for the reader.
  135. Rusty Russell's comments are great. by Mr.+Fred+Smoothie · · Score: 2
    In the iptables code (can't remember if it was the userland code or the kernel code), I remember seeing:
    • A comment to the effect "If you don't understand this code, DON'T FUCKING CHANGE IT"
    • a terse line of code which ignored the return value of a called function with a comment to the effect "Look at that: laziness, impatience and hubris, all on one line!"
    --

  136. 3 words by Mr.+Fred+Smoothie · · Score: 2

    Spreadsheet
    flight
    simulator

    --

  137. Re:type* var is evil by IvyMike · · Score: 2

    I tend not to use multiple declarations per line; the problems outweigh the positives (With multiple declarations: You cannot comment variable usage later, it's (slightly) more typing to refactor code by removing or changing variables, and there's the problem you bring up).

    Once you've adopted that rule, it's a lot clearer (and closer to the truth) to use "type*", since the actual type of "var1" in your example is "pointer to type", not "type".

    It's also the style Bjarne uses in his code, if that makes any difference to you.

  138. Have a team standard by sohp · · Score: 2

    Use a tool like doxygen to formalize your comment formats. The Mozilla project has a page for their doxygen-generated documents at the Mozilla/SeaMonkey Code Documentation and Cross-Reference.

    In the Java world, Sun has a couple of documents on how to comment code, How to Write Doc Comments for the Javadoc Tool and Requirements for Writing Java API Specifications. Note that the latter references Object Class Specification by Edward V. Berard, Essays on Object-Oriented Software Engineering, 1993 Simon pp. 131-162., which is an excellent read in general.

    All that said, please read and live Martin Fowler's comments on coding style and comments in "Refactoring: Improving the Design of Existing Code"

  139. Re:Variable Names -consistency by DrCode · · Score: 2

    All variable names should be variations on "xyzzy". Examples are "xyzzy1", "xyzzy2", "xyzzy3". When you get too many of those, you can start putting the digits in the middle: "xy1zzy", "xyz3zy". And you can also vary the capitalization: "xYzzy".

    Finally, if you still need more names, you can use "plugh".

    These also make good passwords.

  140. Re:Describe your design decisions and thought proc by Fulcrum+of+Evil · · Score: 2

    why the hell are you using 'class'?

    Because this is Java and Java lacks structs

    --
    "We returned the General to El Salvador, or maybe Guatemala, it's difficult to tell from 10,000 feet"
  141. Re:Braces by IvyMike · · Score: 2

    I can only blame the fact that I was posting to slashdot late at night, and also not in the enivronment of an editor, because I would really format functions like this (at least in C++):

    int
    function_name(int x, int y)
    {
    int* z;
    printf("hello\n");
    return 99;
    }

    Briefly, the important points are this:

    • The return type has a newline after it, so the function name is rammed up against the left side. This way, the regexp "^function_name" will only appear one place in all of the code, at the function definition. Now you can type "egrep ^function_name *.C" and get what you were looking for.
    • The braces are rammed up against the left wall. In vi (which I don't use often) you can easily jump to such braces (I belive "[[" and "]]", though I could be wrong), making function navigation easier.
    • Four spaces for indent. Yeah, Gnu uses two and Linux uses eight (or is it a tab?); however, in my opinion, two isn't visually distinctive enough, and eight is excessive and wastes screen space. I know the Gnu people and the Linux people can both justify their decision, but to me, four just looks better. (If it's not clear to you why non-power-of-two indents are aesthetically unappealing, you should reconsider being a programmer.)
    • Spaces for indent, never tabs. See JWZ's document "Tabs vs. Spaces" to see why. He also explains how to set up emacs and vi to do the right thing for indent.
    • Eighty columns, unless you really can't fit it in. It's much easier to print code formatted to eighty. If you never print code, then it's much easier to merge code side-by-side if it's formatted to eighty. In this day and age of reallyLengthyVariableNamesAndAPIS, it can be tough, so if you have to break this rule in rare cases, it's ok, but only if you tried your hardest.

    I've been programming in Java a lot recently, though, where all your functions are in a class scope and therefore the "ram it up against the left" set of tricks doesn't really work. In this case, I tend to format like my original example. Mostly, I think, just to save vertical space.

  142. As this will never be seen by the like of man... by feloneous+cat · · Score: 2, Insightful

    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.

    --
    IANAL, but I've seen actors play them on TV
  143. Re:type* var is evil by Jaeger · · Score: 2
    If you find yourself having to comment the variable...
    then you might be in a freshman-level cs course.

    (it was long ago, but I'm still bitter.)

  144. Comments by counterexample by slamb · · Score: 3, Informative

    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,

    • The huge block comments have these banners that are at column 1, in complete defiance of the indentation. Consequently, the indentation is not at all consistent across the code. It makes it difficult to visually see what level you are at. It makes using a folding text editor impossible.
    • there are lots of comments along the lines of "// slamb was here, 4-26-02". These are things much more appropriate for a version control system (cvs annotate). They clutter up the code unnecessarily.
    • the comments that are there explain nothing. For example,
      // This is the main method that Java invokes at start-up

      That should be obvious from the "public static void main (String argv[])".

    • They are not in the proper form for Javadoc, Doxygen, or any other documentation generator. If you go to the trouble of putting comments at the beginning of methods in structured way, you should do so in a way that can be used to generate easily browsable documentation. See Writing Documentation Comments at Sun.
    • The grammar is inconsistent and awkward. That same document gives hints on making useful documentation with grammar that does not distract.
    • The code is not self-documenting. If you adhere to a consistent coding standard, like Sun's Code Conventions, you will know what a lot of stuff is without resorting to comments at all.
  145. Re:type* var is evil by emag · · Score: 2

    Unfortunately, the precedence tables for operators says you're wrong.

    --
    "The urge to save humanity is almost always a false front for the urge to rule." --H.L. Mencken
  146. Wait till you've almost forgotten it by vanyel · · Score: 3, Insightful

    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.

  147. First, use a good language... by frank_adrian314159 · · Score: 2
    Use a language that reduces the need for comments.

    Let's take for example, C++. If a variable is passed by pointer or reference, you need to document whether it is being passed that way because it is altering the contents of the object or for efficiency (Yes, I know about const. Do you know about the debate over logical const-ness, that destrys the usefulness of the idea?) You have to document allocation and deallocation strategies. You have to document how array limits are passed. If something points to an interior of a structure, you have to document that, too. Old coding habits pop up - like allocating booleans as bits in a word - you need to document those. And, oh yeah, make sure that you document whether the int you are returning is really being interpreted as a boolean, too. There are more examples, but that's enough to make the point. C++ requires more documentation because it has a richer set of ways to do things at the micro-level of the system, any of which that can be translated to the macro-level, where it has very little effect on the logic of the system, but huge effect on the way the system is coded and interpreted.

    So my first recommendation is to use a language where less needs to be documented. Lisp or Smalltalk come to mind immediately; Java or Python in a pinch.

    --
    That is all.
  148. You are a moron by RelliK · · Score: 3, Interesting

    1. Your "improved" code is much less readable than the original. Whoever has to maintain it will need more time to comprehend it.

    2. You introduced a bug on line 3 (null pointer dereferencing).

    Yes, I have personally seen code like it and I wanted to shoot the fucking idiot who wrote it.

    --
    ___
    If you think big enough, you'll never have to do it.
    1. Re:You are a moron by Bob9113 · · Score: 2

      2. You introduced a bug on line 3 (null pointer dereferencing).

      I didn't write a unit test, since this is example code written off the cuff (I know, there's no good excuse for not writing the unit test first - forgive me). My unit tests include bounds tests. The first pass would have induced me to change the code to "".equals( string ).

      1. Your "improved" code is much less readable than the original. Whoever has to maintain it will need more time to comprehend it.

      I disagree. I believe that the use of the variable name "definedForThisUi" more concisely states the intent of the conditional than the first example. Typically a person is more interested in seeing the high level meaning of the aggregated condition that allows entry to the block than the collection of states that must be evaluated in assessing that aggregated condition. This is the reason for creating aggregating conditional methods, such as person.isEligible(), which checks the state of several parameters (perhaps age, membership level, and purchase history).

      Moreover, one stated objective was to make it less likely that the explanation of the code would diverge from the logic. Comments have a nasty habit of not changing when someone alters the logic - but when the code is the commentary, they cannot mutate independantly. Also, programmers tend to be more anal about the clarity of code than they are about comment revision.

      Of course, this code is doing two very simple boolean checks - hardly necessary to clarify this small, simple block - but then, it is just an example. Perhaps you have heard of books on programming style. They typically show small examples which do not, strictly speaking, require the enhancement in question. These examples are meant to demonstrate the concept. Getting the most from examples like this requires that you abstract the meta information - the reason behind the action. A fine example is chapter 1 of "Refactoring". Buy a copy - it is really quite good - and read paragraph 3 of chapter 1 for a more clear explanation.

      Yes, I have personally seen code like it and I wanted to shoot the fucking idiot who wrote it.

      I do not understand how this statement was intended to support your positions, so I do not know how to respond. FWIW your attitude does not sound conducive to a team atmosphere. Have you been fired a lot? Have you ever considered rage management therapy? Screaming into a pillow is supposed to help. JM2C.

      You are a moron

      moron Pronunciation Key (môrn, mr-) n.
      2. Psychology. A person of mild mental retardation having a mental age of from 7 to 12 years...

      I find it hard to believe that the typical moron would care about code commentary and be inclined to express an opinion - regardless of your impression of that opinion. Besides, would a moron use big words like "mutate" and "induced"?

      :^P

    2. Re:You are a moron by ahde · · Score: 2

      the probles with your code isn't in the naming convention -- which is an improvement, but you've got operations and assignments on the same line, which are then assigned to temporary variables (boolean at that!) which then need to be checked (with a boolean operator yet!) later on, where you have to remember what the boolean values represent.

  149. Comments as pseudo-code by booch · · Score: 2

    When I write code (even code that nobody else will see) I write it as psuedo-code in comments first. That lets me get it straight in my head before I write the code. It seems to help -- it makes my coding go quicker.

    My comments don't go as far as your examples. Instead of "loop through the employee records" and "print the record" I'd write "print all the records".

    --
    Software sucks. Open Source sucks less.
  150. Variable name length by vrmlguy · · Score: 2

    One of the best ideas that I ever encountered was that the length of variable names should be proportional to the size of their scope. So, one the one hand, this is OK:
    for (int i=0; i
    (assuming that the "..." doesn't contain any braces), but function/method arguments should be longer, like "name" and "parts" in this:
    int createWidget(string name, billOfMaterials parts) {...}
    and globally-visible items (like the class and method names above) get the longest names.

    --
    Nothing for 6-digit uids?
  151. Variable name lenght (redux) by vrmlguy · · Score: 2

    One of the best ideas that I ever encountered was that the length of variable names should be proportional to the size of their scope. So, one the one hand, this is OK:
    for (int i=0; i<size; ++i) { ... }
    (assuming that the "..." doesn't contain any braces), but function/method arguments should be longer, like this:
    int createWidget(string name, billOfMaterials parts) {...}
    and globally-visible items (like the class and function/method names above) get the longest names.

    --
    Nothing for 6-digit uids?
  152. Refactoring, by Martin Fowler by smallstepforman · · Score: 2

    To quote our good friend Martin Fowler (in reference to Smelly Code):
    "Comments are a sweet smell in code. But sometimes they are used as a deoderant, intented to mask a foul smell. If you need comments to explain a section of code, its time to Refactor".

    Comments will not solve your software maintainance problems. Refactoring will. If you havn't read Martins book, then drop everything and read it. Refactoring, as well as the Gang of Four book, are the most influential books on Software Engineering.

    --
    Revolution = Evolution
  153. Better practice-- inline comments tell why not how by einhverfr · · Score: 3, Insightful

    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.

    --

    LedgerSMB: Open source Accounting/ERP
  154. Wrong book by Bastian · · Score: 2

    If you want one that covers those culprits, read Rapid Development by the same author - it talks about the management end of software engineering. Code Complete is meant to cover the programming end.

  155. Propper comentations by MoneyT · · Score: 2

    Coments shoud, from what I remember from my CS courses.

    a) Describe in detail what the function does, or what the variable(s) store

    b) Describe the preconditions of the function (what has to happen for the function to be called)

    c) Describe the post conditions (what the end result of the function is (what does it return and where does it send the data)

    --
    T Money
    World Domination with a plastic spoon since 1984
  156. Change Risk Management - Unit Testing? by Bob9113 · · Score: 2

    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.

    Contrast this with changing the code, which can safely be done willy-nilly. Thank you for saving us from random code changes by adding blocks of unverifiable natural language which may have a vaguely similar meaning to anyone other than the original author. :-) (now don't get your panties in a bunch, I'm just yanking your chain)

    But if the objective is to mitigate the risk of change, might I suggest trying unit testing?

    Test Infected

    I actually don't worry about the potential adverse side effects in some distant section that might result from improving this section. If it passes the tests, it is right. If it is wrong, it will not pass the tests. If it passes the tests and a bug is later found, it indicates an opportunity for improvement of the unit tests. Enhance the unit tests to reflect the newly discovered requirement, then do the minimal improvements to the code necessary to pass the improved unit test.

    I will make you two promises: 1. It will feel extremely unnatural at first. 2. If you really commit to it in version n, you will experience less bugs in version n+1. Unfortunately, it is impossible to perceive a bug that never exists, so you will have to have a fairly solid feel for how many bugs to anticipate to fully appreciate the improvement.

    As anecdotal evidence; when I build up a new package, I start with the unit tests for the smallest components first, and gradually build my way up. At the end, I start wiring all the subcomponents together. It is not uncommon for me to spend two weeks developing a collection of classes, and less than an hour debugging them in the final integration.

  157. Re:Variable Names by PepsiProgrammer · · Score: 2

    Exactly, my whole coding philosophy is to name my vairables and procedures so that the code reads as much like english as possible. If i do my job correctly my code should halfway comprehendable by people who dont even know wtf c/c++/java/insertlanguagehere is

    --
    "The United States has no right, no desire, and no intention to impose our form of government on anyone else." - Bush 05
  158. Re:Variable Names by emag · · Score: 2

    Actually, they weren't. I can't quite say who they were, but you're about as far away as you can get from what they do...

    --
    "The urge to save humanity is almost always a false front for the urge to rule." --H.L. Mencken
  159. Re:Simple rule of thumb by nagora · · Score: 2
    I think this shows one problem: people mix the documentation and the code. Long comments in code make life difficult/anoying for people that know the code. Comments in the code itself should be short and consist mainly of hints.

    The documentation should ideally be in a separate document which explains each subroutine/function. But this much discipline is way beyond most programmers!

    One of the reasons I like Forth is that any decent Forth system allots an equal amount of space for comments as code but in a way which does not interfere with the code. A Forth editor can then display a block of code with the corresponding block of comments beside it. Also, since the comment block is assigned anyway you feel you should put something in it so I find I comment Forth programs quite well as I go along.

    TWW

    --
    "Encyclopedia" is to "Wikipedia" what "Library" is to "Some people at a bus stop"
  160. Re:so YOU'RE the guy... by Cederic · · Score: 2



    Hmm. The code I delivered last week (50 java classes, another 45 unit test classes using JUnit) has approx. 1 Javadoc comment per public method.

    That comment contains detail on what the inputs need to be, what the outputs will be, and what error conditions can occur.

    The code itself uses sensible variable names (there are no single letter variable names in my code) that describe what's going on. As only two of my methods are more than 15 lines long, this means that the code is extremely easy to read and very maintainable.

    Those two methods are non-trivial btw - and both of them were ones I just lacked the time to refactor, or they would be shorter. And both contain inline comments, because the code is not clear. Oddly enough, I hate this, but I've done it because I recognise the necessity. One day I'll get the time to write an internal rate of return calculation that's properly refactored and doesn't need comments, and still performs adequately, but until then I guess I'll stick with the comments.

    In my experience, people do not update the comments. They do not update the technical spec, and they do not update the functional spec. I focus on delivering workable maintainable code, and putting in comments that people will neglect and will (at a later date) mislead people does not make the code maintainable. If you work in an environment where comments are regularly updated, congratulations - I don't, and I've never met anybody who does.

    ~Cederic

  161. Re:Variable Names by Pig+Hogger · · Score: 2

    Fashion designers?

  162. Re:type* var is evil by Chris+Mattern · · Score: 2

    > You missed my point entirely. *foo is not a character. *foo is a pointer,

    No, foo is a pointer. *foo is a dereferenced pointer, which means, since foo is defined as a pointer to char, it is a char. The fact that the pointer must be properly defined before it can be dereferenced does not change that.

    > Saying that *foo is a character implies that you can do something like *foo = 'A';

    No, it doesn't imply that. Saying that *foo is a static character variable implies that, but of course, it isn't, and we never said it was.

    Chris Mattern

  163. Re:Variable Names by mustangsal66 · · Score: 2, Informative

    I once worked with a guy whos favorite variable and was asdf (Just roll your left hands fingers across the keyboard), and when he needed another he'd roll his fingers the other way(fdsa). It was maddening to debug. I find it useful to comment each section with what the code chunk expects in terms of data in, what it does with this data, then how and where it returns the data. I sometimes also note my thought process in writting the code this way. There are also times when I don't comment the code at all... especially if it's a chunk for an embedded box with limited storage. I do write docs for it, but they're stored elsewhere. -Just my $.02

    --
    Why worry? Each of us is wearing an unlicensed "nucular" accelerator on his back.
    Sig changed for readability by G.W.
  164. Re:Variable Names by UnknownSoldier · · Score: 2

    I allways (when applicable) add a prefix to my variables that identifies the type. Name then becomes sName, etc. I know this does not work for everybody,

    Hehe, why are programmers so passionate about HN. Seems like coders tend to fall into 2 camps - they hate it, or they see the underlying merits, and use a modified version.

    Years ago I absolutely hated Hungarian Notation. IMHO it was far too meticulousness - you spent more time trying to keep your variables up to date, then coding! (Ok, it wasn't that bad, but close.)

    You can see how painfull raw HN is:

    Microsoft Hungarion Notation

    Does one *really* need to be that preverse about specifying the difference between byte, char, short, long, dword? Sheesh !

    (Notice how this pattern shows up when you take any good idea / methodolgy and become a "zealot" about it, but I digress.) Most of the time you don't need to split hairs over ints, floats, bools, chars, strings, etc. You're just making busy-work for yourself.

    That said, here's a heavily modified HN (namely a lot less restrictive) for C++ that I find extremely handy:

    • s static
    • g globals
    • _ member variables

    There are a few variations on this: Microsoft uses m_ (I don't care for this style, as this is too "wordy" IMHO), Some of the well know C++ gurus (forgot if it was Eckel or Meyers) use a trailing _ (again too easy to miss IMHO)

    • p pointers
    (s, g, _, p are always in this order)

    I find these to be a good compromise:

    • n for any number / int / float
    • i index / iterator
    • a array
    • r reference

    And since I'm dealing with so much 3D math I also use:

    • v vector
    • m matrix
    • q quaterions

    To keep track of what I'm converting to/from.

    ~ 2 ~ Having a standardized coding standard at work has been a Good Thing (TM) in the long run. I didn't like it at first, (habits and all :) but it's made working on other peoples code easier.

    ~ 3 ~ I can't stress this next tip enough: Use *descriptive* variables names.

    A descriptive name almost takes away the need for comments (almost ;-)

    i.e.

    If you iterating over a set, or range, say it !

    for( iCard = 0; iCard < nCards; iCard++ )

    ~ 4 ~ Use whitespace. Align the columns of your tables up. There is a reason tables exist - to make it easier to read.

    ~ 5 ~ If you have a function that does some complex calculation, document where you got the formula from.

    i.e. See Graphics Gems Volume N, Pages nn-nn

    ~ 6 ~ As you come up with ideas for how the block of code you're working on could be better, made more robust, effiecient, etc, put a comment: // TODO: rewrite so is cleaner

    This way you can do a search to see which parts of the code needs to rewritten.

    Cheers


    --

    "The issue today is the same as it has been throughout all history, whether man shall be allowed to govern himself or be ruled by a small elite."

    - Thomas Jefferson

  165. I've seen genuine long functions plenty of times by Anonymous+Brave+Guy · · Score: 2
    I've never seen a method over 20 lines that really needed to be that long.

    I use them every day. Some of the code I deal with performs complicated mathematical algorithms. The functions run to 100+ lines. The algorithm is a compete entity in itself. It has no logical subparts. It does not decompose into meaningful steps. It just does a whole bunch 'o maths. Are you suggesting that I should refactor this code into separate parts at some arbitrary points just to keep the code shorter than 20 lines per function?

    All the evidence I've ever seen says that not only do longer functions not harm readability (up to a limit of around 150-200 lines, at least), arbitrary decomposition such as you advocate does harm readability, because it forces the reader to jump around for no good reason.

    --
    If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
  166. Re:Variable Names by Salamander · · Score: 2

    I don't think you need to be quite so anal about it. Comments or variable names that are uninformative are bad, whether they're intended to be funny or not. Comments or variable names that are informative are good, and making a dreary chore out of anything discourages people from doing it. I'll take good comments with bad humor over no comments at all any day.

    --
    Slashdot - News for Herds. Stuff that Splatters.