how do you write your comments?

^^^^^look at topic name^^^^^

over every function I have a comment with a list of keywords so that if I ctrl-f I can find the function easily if I forget what it is called. like if I had a function that did math stuff:
//math, division, add, adding, subtraction, +, - and so on
1
2
3
4
5
int mathsuff()
{
code stuff
return answer
}

For normal comments I write them like this:
1
2
3
//#1
//line1: some stuff
//line2: some more stuff 

I do it this way so that in other comments i can say something like this:
1
2
//#13
//line1: for explanation of what this does see #6 line4 

so how do YOU write your comments?
Last edited on
doxygen compatible comments
1
2
3
/**
* Something like this
*/

for documentation, comment lines as remarks for myself what is happening inside a function:
1
2
//the following does something
do_something();

And inline comments to explain function parameters and struct members:
1
2
3
4
5
structb b = {
x,                 // For ClosetedBL support
y,                 // For StraightLetter support
z                  // Halfscreen
};


And of course, avoiding adding too many or too long comments, because those tend to make the code actually LESS readible.
I guess were the only ones who comment our code ;p
I generally only comment why I am doing stuff (e.g. "I used a bitshift here because it's faster").
Occasionally I will comment on what if it is obscure (e.g. "xoring with this int gives me the last 8 bits of this number, which is blah blah...")

Other then that, I don't really bother because my functions/variables generally have names that describe what they do and thus don't really need comments.
if you need lots of comments you're probably not programming very well, which is basically what firedraco said. Use descrptive variable and function names and only comment sections that have some complicated quirk which really needs explaining. Also, comments shouldnt normally explain what a piece of code does, as that should be apparent, most of the time they should describe why they do it in a particular way or why it was necessary to do it at all.
Last edited on
I think that neither documenting return values (where they are not self explanatory) and function parameters that only make sense for certain sets of values hurts. Of course that documentation doesn't necessarily have to be inside of the code (and in fact, shouldn't), but a short this and, as you mentioned, because where it is not obvious doesn't hurt. (e.g. with really complex statement a short what as a reminder for yourself to save you the headache of deciphering it later on doesn't hurt).
I rarely use comments. I'll only use them if I think there's a chance I could forget why I did something, or for a TODO or FIXME.

When I do use comments, they're usually one-liners and unrelated to each other. :)

-Albatross
I don't comment.

<coolface>
Lots of doxygen comments on the public interface: invariants, preconditions, postconditions. Sometimes 2:1 comments to code. My code lasts for years and will be used by others.
write comment use you like format
What's a comment? Never heard of such a thing!

Seriously though, I only comment on ambiguous functionality, or occasionally a seemingly random bit of code, and only rarely todo stuff.
closed account (3hM2Nwbp)
My commenting strategy complies with Doxygen. I've been writing a bunch of library code lately, so each method has the following documented guarantees / expectations. Doxygen output makes documentation look quite sharp, and a good deal less clunky than reading through header files (imo).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/// Brief description of method
/**
 * @pre
 *    Any preconditions that this method requires
 * @post
 *    Any postconditions that result because of this method
 * @param [0, n-1] paramName
 *    Brief description of parameter
 * @return
 *    Brief description of return value
 * @throw
 *    An EXPLICIT throw specification - including which guarantee it offers (basic, strong, nothrow)
 *    and WHY the various exceptions may be thrown.
 */


*Edit -

My implementation usually contains absolutely no comments (unless when arcane tricks are used). (Or to leave myself notes for when I come back to it later, so I'm not forgetting where I left off!)
Last edited on
In the file header a put a detailed description of what the file (class) does and why the file (object) was created if there is a technical reason. If the object's inner workings aren't painfully obvious (most of the time not -- there is no such thing as software that is too simple), I also put a high level design (not long -- the longest I've ever written was maybe 4 paragraphs) that someone who has never seen the code before can read and get a basic understanding of how the object works and how all the object's data members work.

For each function, I document precisely what the function does and what the function returns for all given inputs, valid or invalid. Example:

1
2
3
4
5
6
// Uses rand() to return a random number distributed uniformly in the range [ low, high ].  If 
// high > low, throws std::range_error.
int get_rand_range( int low, int high )
{
    // ...
}


If the implementation of the function ignores return codes, this must be documented either at the particular line of code or in the function header as a warning to future developers. If making certain changes to the implementation of the function would require changes to other functions, this must be documented. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Sets the size, in pixels, of all of the controls to be placed into the dialog box.
// Warning:  this function works in tandem with draw_controls() in that if you change
// the size of a control, you might need to adjust the x,y coordinates at which the
// controls get drawn.
void size_controls()
{
    myDropBox.set_size( 200, 50 );

    // Buttons are sized the same because non-uniform button sizes look weird
    okButton.set_size( 100, 50 );
    cancelButton.set_size( 100, 50 );
}

// Draws the controls in the dialog box if they have not already been drawn or are out-of-date.
// If the controls have already been drawn but are out of date, they are first removed, then
// redrawn.  If the controls have already been drawn and are up-to-date, this function does 
// nothing.
//
// Warning:  this function works in tandem with size_controls() in that if you change
// the size of a control, you might need to adjust the x,y coordinates at which the
// controls get drawn.
void draw_controls()
{
    // ...
    
    // Warning: positions of these controls are dependent upon their size.  See size_controls()
    myDropBox.show_at( 10, 10 );
    okButton.show_at( 10, 80 );
    cancelButton.show_at( 120, 80 );
}


Individual lines or blocks of code should be documented if there is something non-obvious about them. For example, if it is not obvious that line 3 _must_ be executed before line 4, it should be documented. If it isn't obvious why the line of code is there in the first place, it should be documented. Do not document what the line does unless it is not obvious. Examples:

1
2
3
4
5
6
7
8
9
10
11
12
13
// Copies the file "src" (which may contain a path) to "dst" (which may contain a path).
// If "dst" already exists, it is overwritten.
//
// Returns true if the file was successfully copied, or false in all other cases.  If false is
// returned, the destination file is not modified.
bool copy_file( const std::string& src, const std::string& dst )
{
    std::ifstream input_file( src.c_str() );

    // Per API, we don't want to touch dst if src can't be opened.
    if( !input_file )
        return false;
}


Example of bad comments:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
bool copy_file( const std::string& src, const std::string& dst )
{
    std::ifstream input_file( src.c_str() );

    if( !input_file )
        return false;

    // Create the output file (BAD: DUH, isn't it obvious that's what this line does?)
    std::ofstream output_file( dst.c_str() );

    // Loop while not at EOF of the source file  (BAD:  DUH, isn't it obvious we'd do that?)
    while( input_file )
    {
        char ch;
        input_file >> ch;  // Read one character (BAD: DUH, obvious.  Maybe say why one
                                   // character at a time since this as bad as a file copy implementation
                                   // could get.)

       if( input_file )
       {
            output_file << ch;  // Write to output file (BAD: DUH... obvious again.)
            if( !output_file )
                 return false;
      }
   }

   return true;
}


I avoid putting lengthy comment blocks in the middle of a function just because it detracts from the readability of the function by making the code lines far apart. If I can't explain succinctly yet thoroughly what I want to explain at the line of code, I'll put a block of comments in the function header and perhaps document the line of code with a one-liner and a "see function header for details".

I generally use doxygen-friendly comments, however I don't document things exhaustively just to make the doxygen output complete. For example, I don't use param comments for every parameter on every function. Sometimes its just too obvious and there isn't really anything more to say beyond the name of the parameter.

I also don't use comments just to adorn the code and make it pretty. Comments are to facilitate understanding, not to make the code pleasing to look at. That means skipping
the * on the right side of the comment block -- adding a box of asterisks around the comment does not aid in understanding the code and is, quite frankly, annoying to have to maintain.

Last edited on
closed account (zb0S216C)
I tend to write a small descriptive paragraph above the variable/member/method/directive to describe what it's purpose is.
1
2
3
4
5
6
7
8
9
10
11
12
13
// Copies the value from the source integer into the destination integer.
// False is returned if either argument is NULL. Else, true is returned on
// a successful value transfer. 
bool My_Method( const int *Source_int, int *Dest_int )
{
    if( ( Source_int != NULL ) && ( Dest_int != NULL ) )
    {
        *Dest_int = *Source_int;
        return true;
    }

    return false;
}


If the operation or procedure is not obvious, it doesn't need commenting( I learnt this from the a previous post which I'm sure most of you remember ).

To me, the above sample comment gave me an idea of what values it returns and what it does before reading the actual body. As this is a sample, I don't really follow the rules of useful commenting.
Last edited on
Topic archived. No new replies allowed.