Tag Archives: coding style

Un-learning your coursework: Commenting

In an effort to not lose points on their grade, many students will end up writing code like this:

#include <stdio.h>   // For input and output
#include <string.h>  // For string-related functions

// Main method
int main(int argc, char* argv[])
{
    int numChars = 0; // create integer variable numCharacters and set it to 0
    for (int i = 0; i < argc; ++i) // loop once for each argument
    {
        numChars += strlen(argv[i]); // add the length of string argv[i] to numChars
    }
    printf("Number of characters in arguments: %d\n", numChars); // Output the calculated number of characters
    return 0; // no errors while running
} // end main

The excess of comments clutters the code and makes it less readable, the exact opposite of your goal. Even worse, some graders will take points off if you don’t comment this heavily. Ugh.

For your coursework, just go along with whatever the instructor asks for; commenting style is not worth sacrificing your grades over. In the meantime, start un-learning some bad habits by considering the advice below.

Don’t point out the obvious.

Let your code speak for itself. Any programmer who looks at your code will know that “++i;” means that i is being incremented; you don’t need to repeat that information. The same goes for common programming idioms; for example, it’s pretty easy to recognize “for (i = 0; i < value; ++i)” as looping through something value times.

Save comments for when you’re doing something subtle or unintuitive. Of course, if you end up in that situation, remember this next guideline:

Bad code requires many comments. Good code needs few.

If you’re anything like me, your first impulse when you realize your code is hard to follow is to write a comment explaining it. However, “just comment it” shouldn’t be the first solution. If possible, try to re-write the code so it’s clearer.

Comment bug fixes.

Depending on how you fix a bug, it might be worth putting a comment there explaining the bug you just fixed. It prevents the problem of someone coming along later (possibly even yourself!) and saying, “This is over-complicated. I’ll just re-write it to be simpler…” and re-introducing a bug you already fixed. That being said, if you’re using unit tests, you’re probably safe if you just write a regression test for that bug and call it a day.

// Good example: explains a possibly unintuitive piece of code
void updatePlayer(Player& player)
{
   ...
   if (player.x > CAMERA_BOUNDS)
      doSomething();   // BUGFIX: Prevents the edge case where [...]
   ...
}

// Bad example: points out the obvious
void someFunction()
{
   int x = 0;
   while(x < 10)
   {
      ...
      ++x; // BUGFIX: loop didn't end
   }
}

Comment function headers.

You can probably guess what this function does if you find it in a header file:

float max(float x, float y);

However, you don’t want to code based on “this function probably does what I want it to.” You’ll probably go through the code and double-check what it does – no big deal, the function is only two lines anyway, right? And then so will everyone else who uses this function. Every. Single. Time.

You don’t necessarily need a super-verbose JavaDoc-style comment at the top of every function, but you should at least write a quick comment saying what the function does:

// Returns the greater of two floats
float max(float x, float y);

Furthermore, if someone else forgot to add in that comment, write it yourself after you figure out the function and save everyone some time. Make sure you’re correct, though! Incorrect comments are worse than no comments in most cases.

Stick to established commenting styles

Even if there’s no official, formal commenting policy for a project, please keep your new code consistent with the old. Remember just above where I said “You don’t necessarily need a super-verbose JavaDoc-style comment…”? That doesn’t apply if every other function in your project has one. Consistency trumps personal preference here.

Follow these guidelines judiciously.

No rules are set in stone. Let’s say you’re using a super-fast but super-complex algorithm because you’ve optimized that part of your code heavily. Of course it’s going to require a lot of comments. Just make sure to keep that complexity encapsulated behind a nice interface.

With that, I’ll leave you with how I would personally write the program at the top of this post:

// Arglength - Prints the total number of characters passed in as arguments, including the program name
// Author: Zachary Hoefler

#include <stdio.h>
#include <string.h>

// Entry point
int main(int argc, char* argv[])
{
    int numChars = 0;
    for (int i = 0; i < argc; ++i)
    {
        numChars += strlen(argv[i]);
    }
    printf("Number of characters in arguments: %d\n", numChars);

    return 0;
}

Learning Lua

Sticking to my plans, I’ve begun teaching myself Lua. Although it’s a bit odd to wrap my head around after just diving head-first into C++, it’s pretty cool!

One lesson I’ve learned (or, rather, had reaffirmed) is how important writing clean code is. Given Lua doesn’t require semicolons to separate statements and doesn’t use braces, you can get away with some really sloppy, hard-to-read stuff. The following are all equivalent:

-- Easy to read factorial function
function fact (n)
   if n == 0 then
      return 1
   else
      return n * fact(n-1)
   end
end
-- Hard to read, but simple enough where you could probably figure it out
function fact (n) if n == 0 then return 1 else return n * fact(n-1) end end
-- Oh boy.
function
fact
(n) if n ==
0 then return
1 else
return n *
fact(n
-1) end

end

Having only really worked with C#, C++, Java, and ActionScript, it’s going to take some effort getting used to the syntax of Lua; however, I’m up for the challenge!