views:

355

answers:

12

Sometimes I want to write a "major" comment to describe a large block of code and then write "minor" comments to describe a few of the lines within that block of code:

// Major comment

// Minor comment
...

// Minor comment 2
...

The major comment looks strange without code directly beneath it, and you can't visually tell how much code it is describing below.

How do you style these comments?

(I remember reading about this in Code Complete a while ago but I don't own the book.)

+1  A: 

I use something like this, to make it look more like a "heading" or separator for the following block of code:

// ***** Major comment *****

// Minor comment
...

// Minor comment 2
...

Of course that assumes that the "major comment" is only a few words

Marc Novakowski
Me too. *********** make it stand out. I also use " <=====--------- NOTE USE OF CONTINUE INSTRUCTION" whenever I have one of those buggers.
TheSoftwareJedi
+1  A: 
// Major comment
// -------------
...

// Minor comment
...

... // Minor comment (end of line)
cschol
+3  A: 

I use multi-line comments for 'major' comments:

/*
 * yada yada yada
 */

And use the single line comments for the minor ones.

I know some people don't like using /* */ style comments because it makes it harder to automatically comment and uncomment blocks ... but I like how they look, and I'm a strong believer that code should be aesthetically pleasing to read.

That also means that you should be able to parse the structure of the code largely without reading the details, which means I tend to use quite a lot of whitespace and also seperator comment lines to help break things up. So for a block I want to comment I might write:

/**
 * detailed description ...
 */

code

// -- minor comment
code

code
// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
Rob Walker
I really hate this style of comment!
Mitch Wheat
you may like the argument of the guys writing the Rationale document for C . they say they haven't considered nesting support for /* ... */ since uncommenting blocks should be done with #if 0 ... #endif, because comments should really only be for documenting the code, and not for disable parts of it
Johannes Schaub - litb
A: 

I put major comments above the code (block), preceded by a blank line, and sometimes in all upper case. Minor comments I put off to the right, indented to column 81 to get them out of the way of the code. Both of these using //.

For algorithmic "discourses" I use a /* */ like so:

/*
 * This is a long discourse on the code which follows it, usually
 * placed at the beginning of a method and containing information
 * which is not appropriate for the doc comments.
 */
Software Monkey
+1  A: 

I think the difference between "major" and "minor" comments rests on the program structures to which they are attached. For example, I consider method- or class-level documentation comments as "major" and block- or line-level comments as "minor":

/**
 * This is major comment describing the method
 */
public void foo() {
    if (...) {
        // minor comment describing block
        ...
        doSomething(); // minor comment describing line
    }
}

Rather than chopping up your code with comments, I think it is a good practice to refactor functional units into their own methods with descriptive names and doc comments.

Brett Daniel
A: 

I would do it like this possibly:

// Here we do it
//
// So, be aware this text is just to make a silly
// long comment to show how it would look like 
// in real code. 
doTheRealThing();

// and this is another thingy
doOtherThing();

If the comment documents some code that appears between other code blocks, and i want to really make clear where the comment refers to, occasionally i catch me writing blocks around the stuff

// prepare for party
doIt();

// Here we do it
//
{
    // So, be aware this text is just to make a silly
    // long comment to show how it would look like 
    // in real code. 
    doTheRealThing();

    // and this is another thingy
    doOtherThing();
}

// another code that is not really affected by the comment
// above
die();

Sometimes the block needs its own set of local variables to accomplish the task, and then the block also serves to reduce the scope of them to the place where they are needed. Arguably, such code should be put into their own respective function, but it occasionally happens doing that will decrease code quality. Now, for commenting methods, i generally only comment them in their header file, and do it by something like this:

/**
 * This function will return the current object.
 *
 * And now it follows the normal long stuff that's again
 * a bit stretched to fill space...
 */
Object getCurrentObject();

For uncommenting ranges of code, i explicitly do not use those comments, as i reserve them only to document code. I gonna use

#if 0
    Code in Here that's disabled
#endif

And it also will save me from having some stuff that is not valid C++ code (stuff in between those delimiters still have to contain valid tokens). I'm not sure how the matter is in C# about it, though.

Johannes Schaub - litb
A: 

This is all pretty C centric here. In C/C++ I tend to write

/* file -- what it is -*-emacs magic-*- */

As the first line.

/*
 * Block comments like this
 */

if( I need a comment on a code block) {
   /* I tend to write them like this */
   x = x + 1 ;                        /* ... and write my */
                                      /* line comments so */
}

I usually reserve // comments for inside code, and keep good old BSD comments to the block comments.

In Lisp

;;;; Four semicolons for "file-scope" comments

;;; Three for block comments over a large chunk of code

(defun quux (foo bar)
    "Don't forget your docstrings, folks"
    ;; but big code comments get two semicolons
    (let ((a 1)
          (b 2))                      ; and only one semicolon
          (+ a b)))                   ; means an in-line comment.

# comment languages like Python and Ruby
# Have to live with one style of comment.
def quux(a,b):
    return a + b                          # poor neglected things.
Charlie Martin
thats sucks about Python and Ruby..
featureBlend
A: 

I typically comment blocks of code using /* */ at the top of each section. I don't use inline comments except in special curcumstances (e.g. tricky code) because I feel the comments are "hidden," and the code could be expanded later and comments would have to be micromanaged. For example:

int parseEverything()
{
    /* Initialize the parser. */
    random_code_here();

    still_more_init();
        /// (Note: the above line still falls under the init section, even if it's separated by a newline.)

    /* Main parser loop. */
    while(!done_parsing) {
        /* Grab the token. */
        if(x) {
            /* Preprocessor stuff. */
            y();
        } else {
            /* Normal token. */
            z();
        }

        /* Insert into tree. */
        make_tree_node();
        insert_into_tree();

        /* Move to next token. */
        ++streamPtr;
            /// (Note: the above could be expanded to take up multiple lines, thus
            ///        if an inline comment were used it'd have to be moved, if
            ///        you even remember there's a comment there.)
    }

    clean_up();
}

Of course, if the code is obvious, it shouldn't require a comment, as in clean_up(). Including the comment doesn't hurt much though, and if expanded later it would be easier to know where to put extra cleanup code.

Using this scheme I find it is easy to follow a function solely by its comments. parseEverything has three main sections: initialization, the main loop, and clean-up. Within the main loop we grab the token (preprocessor or normal), insert it into the tree, and move on to the next token.

Most likely each section calls for its own [set] of functions, so it's clear you may need to refactor if sections become bulky.

I should add that I format multiline comments as such (my "IDE" (Vim) inserts the * at every line for me with the default scripts (for my distro), which is convinient):

/*
 * This is a comment which normally would be on one line, but is either split into multiple
 * lines for emphasis or so we don't have 160-character hard-to-read comments everywhere.
 */

Also, I comment #else's and #endif's:

#ifndef FOO_H
#define FOO_H

#ifdef DEBUG
#else   /* DEBUG */
#endif  /* !DEBUG */

#endif  /* FOO_H */

But that's getting a bit off topic.

(#include guards don't require the not (!) to preceed them because their use is obvious, and it's tradition. =])

strager
A: 
// A plate is displayed if a WorkFlowStepUpdate message is received
// whose:
//        * Change_Type is License_No
//        * Event_Type is GA, NA, or NG
//        * New_Value is non-null and non-blank
//        * Inspection_DateTime<(NOW-TimeInMinutesBeforeExpiringDisplaySignMessage)
//
// A plate is removed:
//         * if it has been displayed for TimeInMinutesBefore...
//         * a GA, NA, or NG CloseEvent is received  whose New_Value matches
//           a displayed plate
//
// If a plate is to be added to a full screen, the oldest plate on the display
// is removed to make room for the new plate.


.
.
.
.
.



// Record the ping status of each IP device
foreach (string s in th.Keys)
        {
        // We don't know if this is a wks or svr.
        // But we can rely on 0 being bad, and we'll
        // get the 'proper' state enumeration down in GetsOHInfo
        // 
        if (IsItLive(s)) IPStates[s] = 1;
        else IPStates[s] = 0;
        IPTimes[s] = System.DateTime.Now.ToUniversalTime();
        }
cookre
A: 

Major comment

/***  Function - fooBar()  ****************************
** Description                                       **
**    does the flooble using the bardingle algorithm **
**      with the flinagle modification               **
** Pre-condition                                     **
**    all moths are unballed                         **
** Post-condition                                    **
**    all moths are balled                           **
******************************************************/
void fooBar( int foo ) {
    ...
    ...
}

/***  Function - fooBar() END  ***********************/

Minor comment

// note cast to int to ensure integer maths result
int i = (int)y / (int)x;
duncan
A: 
// Top-level (major) comment
theThing=doSomething();
    // - Second-level (minor) comment
    anotherThing=doSomethingWith(theThing);
        // - - Third-level (minor-minor?) comment
        yetAnotherThing=doSomethingWith(anotherThing);
    // - Back to second level
    destroy(anotherThing);
// Back to first level
helloWorld();

Of course, the identation trick doesn't apply when the syntax doesn't allow it (read: Python)

WindPower
A: 

This is my comment style preference:

/**
 * This is a comment explaining
 * what this method is actually doing
 */
public void foo()
{
 // this is a simple comment
 doSomething();

 // this is a special comment
 // explaining thoroughly what I'm doing
 // using as many words as possible
 // to be the most concise
 doSomethingSpecial();
}
Yuval A