Skip to the content of the web site.

Lesson 1.22: Comments

Previous lesson Next lesson


Before we continue, it is necessary to understand that a programming language describes what a computer must do to accomplish a task. What a function is meant to actually accomplish, however, may not be apparent from the code. For example, what does the following code do?

/* Copyright (c) 1988, Landon Curt Noll & Larry Bassel. All Rights Reserved.
 * Permission for personal, educational or non-profit use is granted provided
 * this this copyright and notice are included in its entirety and remains
 * unaltered. All other uses must receive prior permission in writing from
 * both Landon Curt Noll and Larry Bassel.
 */

#include <stdio.h>
int main(int t,int _,char *a){return!0<t?t<3?main(-79,-13,a+main(-87,1-_,main(-86,0,
a+1)+a)):1,t<_?main(t+1,_,a):3,main(-94,-27+t,a)&&t==2?_<13?main(2,_+1,"%s %d %d\n")
:9:16:t<0?t<-72?main(_,t,"@n'+,#'/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+,/#{l\
+,/n{n+,/+#n+,/#;#q#n+,/+k#;*+,/'r :'d*'3,}{w+K w'K:'+}e#';dq#'l q#'+d'K#!/+k#;q#'r\
}eKK#}w'r}eKK{nl]'/#;#q#n'){)#}w'){){nl]'/+#n';d}rw' i;# ){nl]!/n{n#'; r{#w'r nc{nl\
]'/#{l,+'K {rw' iK{;[{nl]'/w#q#n'wk nw' iwk{KK{nl]!/w{%'l##w#' i; :{nl]'/*{q#'ld;r'\
}{nlwb!/*de}'c ;;{nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+;#'rdq#w! nr'/ ') }+}{rl#'\
{n' ')#}'+}##(!!/"):t<-50?_==*a?putchar(31[a]):main(-65,_,a+1):main((*a=='/')+t,_,a+
1):0<t?main(2,2,"%s"): *a=='/'||main(0,main(-61,*a,"!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:\
\nuwloca-O;m .vpbks,fxntdCeghiry"),a+1);}

You can run this program on cpp.sh to find out what it does.

Now, the above code was intentionally obfuscated, but suppose you came across the following code:

double sinc_1_16( double x ) {
    return (0.5*x*x - 1.5)*x*x + 1;
}

If you saw this code, you may be curious, and you may even look up what this sinc function is. In this case, Wikipedia is an easy source, but $\frac{\sin(\pi x)}{\pi x}$ looks very different from the function implemented above. If a bug was reported about the use of this function, you may try to fix the bug by replacing it by:

double sinc_1_16( double x ) {
    return std::sin( 3.1415926535897932*x )/( 3.1415926535897932*x );
}

All tests should continue to pass; however, there are two serious problems:

  1. If you calculated sinc_1_16( 0.0 ) before, you get the value of 1.0, while now you get NaN (for not-a-number) because it resulted in the calculation of 0.0/0.0.
  2. The new version takes 350% longer to run.

The problem is that this implementation of the sinc(...) function, like we did with the sine function, is an approximation. On the interval $[-1.16, 1.16]$, the polynomial approximation has an absolute error no greater than $0.021$. So it is reasonably accurate. If you were to track down the mistake, it was likely that someone tried to call this function with an argument outside the interval $[-1.16, 1.16]$. For example, ${\rm sinc}(1.42) \approx -0.217$, but sinc_1_16( 1.42 ) evaluates to 6.0575; thus, if the function is called with an invalid argument, the returned value is garbage.

Thus, it is often essential that the programmer comment his or her code so that a future editor of that code understands the purpose. This is critical for an engineer, as it is very likely that:

  1. the person editing the code will not be the one who originally authored it, and
  2. even if the person editing the code is the who authored it, it will often be weeks, months or even years since the code was written.

The programmer reading the code that was written can determine what the code does, but suppose there is an error: the reader does not know what the code was intended to do. Similarly, if the programmer reading the code is attempting to add new features, the programmer must understand what the code should be doing prior to modifying it.

For this reason, every programming language allows you to make comments in English that are ignored by the compiler. In C++, any text between a slash-star pair (/*) and a closing star-slash pair (*/) is a comment. (Note, in comments and ASCII art in general, the asterisks is often referred to as a 'star'.) Additionally, any text on a line that appears after a slash-slash pair (//) up to the end of that line is also treated as a comment. Other symbols are used in different programming languages, such as # in Python and Maple, and % in Matlab.

There are four types of comments:

documentary
These includes information such as the name of the function, the author, date and version.
functional
These comments describe any assumptions that the function makes regarding the current state of the program; the parameters including their type, the units, purpose and any restrictions on their values; the consequences of executing the function; and the return value including the type and significance.
algorithmic
These comments describe how the problem is being solved from a higher level, usually in English together with mathematical descriptions and possibly even ASCII art.
code details
If the code itself is doing something that is very clever and possibly difficult to follow, it may actually be useful to describe what the individual instructions are doing.

Notice that comments do not simply reinterpret what the code does. These are completely useless comments:

double fast_sin( double x ) {
	// Return 'x' times all of one plus 'x' times all of -0.057385341027109429
	// minus 0.11073981636184074 times 'x'.
	return ((-0.11073981636184074*x - 0.057385341027109429)*x + 1.0)*x;
}

double sinc_1_16( double x ) {
    //            1   4    3   2
    // Calculate --- x  + --- x  + 1
    //            2        2
    return (0.5*x*x - 1.5)*x*x + 1;
}

They simply reinterpret what was printed. Unfortunately, I've seen comments like this.

For our fast sine function, it is necessary document this function so that any user who attempts to call it knows exactly what he or she is getting into:

/****************************************************************
 * fast_sin
 *
 * @file       fast_sin.cpp
 * @author     Douglas Wilhelm Harder
 * @date       2018-02-26
 * @version    1.0
 *
 * @param x    an angle (radians) 0 <= x <= pi/2
 * @return     an approximation of sin(x) (dimensionless) with
 *             a relative error no greater than 2%
 * @brief      Approximate sin(x) for 0 <= x <= pi/2
 *
 * @section    DESCRIPTION
 *
 * This function approximates sin(x) for values of x on the
 * interval [0, pi/2] using an interpolating quadratic
 * polynomial p(x) that
 *    1. p(0)     = 0
 *    2. p'(0)    = 1
 *    3. p(pi/2)  = 1
 *    4. p'(pi/2) = 0
 *
 * The maximum relative error is 2% on the interval [0, pi/2]
 *
 * @todo       If there was anything that needed to be done,
 *             list it here
 ****************************************************************/

double fast_sin( double x ) {
	// Use Horner's rule for evaluating a cubic polynomial
	return ((-0.11073981636184074*x - 0.057385341027109429)*x + 1.0)*x;
}

For the sinc function, appropriate comments may be:

/****************************************************************
 * sinc_1_16
 *
 * @file       sinc_1_16.cpp
 * @author     Douglas Wilhelm Harder
 * @date       2018-02-26
 * @version    1.0
 *
 * @param x    a value (half oscillations) -1.16 <= x <= 1.16
 * @return     an approximation of sinc(x) (dimensionless) with
 *             an absolute error no greater than 0.021
 * @brief      Approximate sinc(x) for -1.16 <= x <= 1.16
 *
 * @section    DESCRIPTION
 *
 * This function approximates sinc(x) for values of x on the
 * interval using 1 - 1.5x^2 + 0.5x^4, which is the quintic
 * polynomial that satisfies:
 *    1.  p(-1) =  0
 *    2. p'(-1) =  1
 *    3.   p(0) =  1
 *    4.  p'(0) =  1
 *    5.   p(1) =  0
 *    6.  p'(1) = -1
 *
 *                    5     4     3     2
 * which, if p(x) = ax  + bx  + cx  + dx  + ex + f results
 * in the system of six linear equations:
 *           -a +  b -  c +  d - e + f =  0
 *           5a - 4b + 3c - 2d + e     =  1
 *                                   f =  1
 *                               e     =  0
 *            a +  b +  c +  d + e + f =  0
 *           5a + 4b + 3c + 2d + e     = -1
 *
 * By symmetry, a = c = e = 0, so we are left with a system
 * of three linear equations in three unknowns:
 *                          b +  d + f =  0
 *                                   f =  1
 *                         4b + 2d     = -1
 *
 * Thus a = c = e = 0, and b = 0.5, d = 1.5 and f = 1.
 *
 * The maximum absolute error on [-1.16, 1.16] is 0.021.
 * The maximum relative error on [-1.07, 1.07] is 5%.
 *
 * @todo       If there was anything that needed to be done,
 *             list it here
 ****************************************************************/

double sinc_1_16( double x ) {
    // Use Horner's rule
    return (0.5*x*x - 1.5)*x*x + 1;
}

As an engineer or programmer reading this code, you know exactly what the author meant, and why the choices that were made were made in the manner that they were.

You, as an engineer, will seldom author code on any project. Consider any civil engineering project: do you ever see a civil engineer actually pouring concrete or installing reinforcing bars? A civil engineer designs the project, and contractors are hired to build the project. Similarly, a software engineer designs the software-engineering project, and developers are hired to implement it.

If you as an engineer do not enforce good coding standards, including good comments, you will lose money, because the next developer who needs to correct or modify existing and poorly commented code will be spending more time than is necessary to determine, for example, what the code is supposed to accomplish and how the code achieves the stated goal.

Specific identifiers for anomalies

In some cases, specific identifiers in comments are used to describe specific instances when there is an issue, or anomaly, with the code that will at some point require addressing:

bug
Identifying a known bug that must be resolved at some point.
fixme
Indicating code that must be corrected.
hack
Indicating that the code does not actually actually work, but it is either inelegant or undesirable and should at some point be corrected.
todo
Indicating something that must be done at some point in the future.

Warning

Even if it is in jest, do not include profanity in your comments. Yes, you will find that there are times where you are very frustrated, and one means of relieving frustration is to write your actual thoughts in the comments of your code—with, of course, every intention of removing those comments prior to anyone else viewing your code. Unfortunately, in all likelihood, you'll forget, and it will be a less-than-professional moment in your career when someone else points out your colorful metaphors.

Don't make comments hard to update

Two ways to make comments difficult to update include anything that requires alignment. For example

template <typename Type>
bool Beap<Type>::find( Type const &obj ) const {
  if ( empty() ) {
    return false;
  }

  int h = height();
  int posn = h*(h + 1)/2;                                      // Starting at the
                                                               // bottom left

  while ( true ) {
    if ( array[posn] < obj ) {
      if ( posn == (height() + 1)*(height() + 2)/2 - 1 ) {     // Move down and
        return false;                                          // to the right
      }                                                        //           x  
                                                               //         x   x
      if ( (posn == height()*(height() + 1)/2 – 1)             //      < a  x   x
            && (size() != (height() + 1)*(height() + 2)/2) ) { //     x   *   x   x
        return false;                                          //   x   x   x   x   x
      }
      if ( posn + h + 2 < size() ) {
        posn += h + 2;                                         // Move down to
        ++h;                                                   // the right 
      } else {
        ++posn;                                                // Move across
        if ( posn == size() ) {                                // to the right
          posn -= h;                                           // Move up to
          --h;                                                 // the right
        }
      }
    } else if ( array[posn] > obj ) {
      if ( posn == (h + 1)*(h + 2)/2 - 1 ) {                   // Move down and
        return false;                                          // to the right
      } else {                                                 //           x
        posn -= h;                                             //         *   x
        --h;                                                   //      > a  x   x
      }                                                        //     x   x   x   x
    } else {                                                   //   x   x   x   x   x
      return true;
    }
  }
}

How much work would be required to maintain these comments if, for example:

  • you added or removed a line of code somewhere,
  • added or removed characters in a single line.

This leads to monotonous and frustrating time spent on updating the comments, which usually leads to 1) the comments not being updated, and 2) the comments that are there are more difficult to read as they are no longer lined up.

Another example of poor commenting practice is closing the right side:

/****************************************************************
 * fast_sin                                                     *
 *                                                              *
 * @file       fast_sin.cpp                                     *
 * @author     Douglas Wilhelm Harder                           *
 * @date       2018-02-26                                       *
 * @version    1.0                                              *
 *                                                              *
 * @param x    an angle (radians) 0 <= x <= pi/2          *
 * @return     an approximation of sin(x) (dimensionless) with  *
 *             a relative error no greater than 2%              *
 * @brief      Approximate sin(x) for 0 <= x <= pi/2      *
 *                                                              *
 * @section    DESCRIPTION                                      *
 *                                                              *
 * This function approximates sin(x) for values of x on the     *
 * interval [0, pi/2] using an interpolating quadratic          *
 * polynomial p(x) that                                         *
 *    1. p(0)     = 0                                           *
 *    2. p'(0)    = 1                                           *
 *    3. p(pi/2)  = 1                                           *
 *    4. p'(pi/2) = 0                                           *
 *                                                              *
 * The maximum relative error is 2% on the interval [0, pi/2]   *
 *                                                              *
 * @todo       If there was anything that needed to be done,    *
 *             list it here                                     *
 ****************************************************************/

Again, just creating this monstrosity caused this author significant frustration. Now, if you had to update these comments, you would be equally frustrated trying to keep the right-hand stars aligned.

Elegant comment boundaries

Significant ASCII art can go into making comments so that they stand out or highlight a significant point in a file. In essence; however, they are simply a starting /* with a lot of text between them and a finishing */. For example, a long explanatory comment may be differentiated as follows:

/*
 * Lorem Ipsum
 *
 * Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec faucibus
 * efficitur laoreet. Nulla posuere aliquam aliquam. Curabitur eget massa
 * neque. Duis tortor justo, convallis in rhoncus sit amet, laoreet in elit.
 * Integer lobortis et mauris vitae sollicitudin. Nulla vel neque neque.
 *
 * Aliquam volutpat convallis lectus. In sodales vel felis ac dapibus. 
 */

A description that is of significance for the following section may look as follows:

/****************************************************************
 * Lorem Ipsum
 *
 * Mauris eros urna, pharetra vitae porttitor sed, luctus sed
 * ipsum. Phasellus commodo luctus enim sed varius. Mauris
 * vitae mattis nunc, ut luctus risus.
 *   - Aliquam vitae erat vel ante consectetur varius.
 *   - Nulla facilisi.
 *   - Aenean tempus sodales sapien eu mattis.
 *   - Nunc sed aliquet neque, vitae consectetur leo.
 *
 * Cras et diam vitae nibh vehicula imperdiet vel in neque.
 * Aenean molestie, metus id hendrerit lacinia, tortor tortor
 * fermentum magna, et ultrices tortor enim vel nibh.
 *
 * Sed at fringilla dolor, tristique tempor sapien. Nulla
 * eget velit at lorem tincidunt tempus.
 *   - Sed ultrices, tellus et dapibus lacinia, nulla quam
 *     malesuada odio, eu luctus sapien ligula imperdiet dui.
 *   - Curabitur elementum efficitur molestie.
 *   - Donec posuere dictum est id volutpat. 
 ****************************************************************/

A title to a section may look as follows:

/****************************************************************
 * ************************************************************ *
 * *                  Public member functions                 * *
 * ************************************************************ *
 ****************************************************************/

Every other star, other than the ones either immediately succeeding the first slash or immediately preceding the last slash are a part of the comment and are only included for the benefit of attracting the eye of the reader to these comments.

Finally, many of these can also be done with end-of-line comments:

// Lorem Ipsum
//
// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec faucibus
// efficitur laoreet. Nulla posuere aliquam aliquam. Curabitur eget massa
// neque. Duis tortor justo, convallis in rhoncus sit amet, laoreet in elit.
// Integer lobortis et mauris vitae sollicitudin. Nulla vel neque neque.
//
// Aliquam volutpat convallis lectus. In sodales vel felis ac dapibus. 
/////////////////////////////////////////////////////////////////
// Lorem Ipsum
//
// Mauris eros urna, pharetra vitae porttitor sed, luctus sed
// ipsum. Phasellus commodo luctus enim sed varius. Mauris
// vitae mattis nunc, ut luctus risus.
//   - Aliquam vitae erat vel ante consectetur varius.
//   - Nulla facilisi.
//   - Aenean tempus sodales sapien eu mattis.
//   - Nunc sed aliquet neque, vitae consectetur leo.
//
// Cras et diam vitae nibh vehicula imperdiet vel in neque.
// Aenean molestie, metus id hendrerit lacinia, tortor tortor
// fermentum magna, et ultrices tortor enim vel nibh.
//
// Sed at fringilla dolor, tristique tempor sapien. Nulla
// eget velit at lorem tincidunt tempus.
//   - Sed ultrices, tellus et dapibus lacinia, nulla quam
//     malesuada odio, eu luctus sapien ligula imperdiet dui.
//   - Curabitur elementum efficitur molestie.
//   - Donec posuere dictum est id volutpat. 
//////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////
   // //////////////////////////////////////////////////////////// //
  // //                 Public member functions                // //
 // //////////////////////////////////////////////////////////// //
//////////////////////////////////////////////////////////////////

Questions and practice:

1. In the previous lesson, you implemented the function

double linear_root( double a, double b ) {
	return -b/a;
}

Why is it essential that this function is properly documented. What would happen if someone just saw your function without any comments?

2. Create a clear set of comments describing the function linear_root.

3. Why are documented the units of the parameters and return value of free_fall essential? What could happen if such a function was not properly documented?

4. Create a clear set of comments describing the function free_fall.

5. Write a function that returns the perimeter or area of a two-dimensional shape (e.g., a square, rectangle, circle, triangle, or trapezoid) or the surface area or volume of a three-dimensional shape (cube, cylinder, cone, sphere, triangular-based prism, rectangular-based prism, triangular-based pyramid, or rectangular-based pyramid). Pick an appropriate name for the function and document the function so that a reader who wants to know how to use the function can easily determine what the parameters mean.

6. A programmer wrote the following program to calculate the area of a rectangle:

based pyramid
double recarea( double l, double h ) {
	return l*h;
}

In addition to not having any comments to document the function, what might you suggest are some other issues with this code?


Previous lesson Next lesson