Comments Unhelpful
Here are the top 10 forms of unhelpful comments. “Unhelpful” means either they don’t aid in understanding the program, or they actively obscure understanding of the program. Drum roll, please:
10. Obligatory Comments
/*------------------------------------------------------------------------ ** Destructor ** Purpose: Empty */ CAnonymizedClassName::~CAnonymizedClassName() { DeleteCriticalSection(&m_csProtLock); }
9. Automatically Generated Version-Control Logs
8. Comments Which Name Language Constructs
// Forward declaration class CFlarpDiddler;
7. Direct Translations of the Next Line of Code
void StringLikeClass::ensure_nul_terminated () { // Make sure we don't overflow our allocation if (len+1 > allocated) { // Get new Memory char *newp = new char [allocated+1]; // zero new memory memset( newp, 0, allocated+1); // Debug Check assert(newp != NULL); // Copy in the old data memcpy (newp,data,len); // remove the old pointer delete[] data; // Set the internal pointer to the new allocation data = newp; // increase allocation by 1 allocated++; } // Put on the NULL if( data) data[len] = '\0'; }
6. Comments Which Belong In Version Control Logs
// -JMF 2008-10-01// TPS#9074455. Restatements of Constant Values
Good:
#define TIMEOUT 10000 // in millisecondsBad:
#define TIMEOUT 30000 // 7 seconds4. Comments With the Wanderlust
/* ** Method BuildRequest ** Purpose : Compose packet to process the transaction, and get response */ string AnonymizedClassName::fillLeft(const string str, const int& len, char c) { ...
public void sendMessage(IMessage argMsg) { if (conn != null && conn.isActive()) { //This really shouldn't happen. conn.sendMessage ( argMsg ); } else { throw new Exception ( "Connector unavailable or inactive." ); } }
3. Commented-out Code
2. Summarizations of Well-Named Objects
// Receive event HANDLE m_evtRecvEvent; // service Id std::string m_sServiceId; // Returns the Attributes Structure virtual HRESULT GetAttributes(ATTRIBUTES *stAttrib, int *iStatus); // Disconnects from the Host virtual HRESULT Disconnect(long *iStatus);
1. The Single Comment
There is a rule that if only one comment appears in a file with more than 500 lines of code, the comment will either be 1) the (original) name of the source file, or 2) completely irrelevant.

Rule of thumb: you probably need to comment your data structures more than your code. A four-dimensional array is a lot harder to understand without comments than a four-level nested loop.
And yes, I’ve had to maintain four-dimensional arrays. That had no comments.
I disagree with some of these; comments that explain the next line of code are nice because they help you understand what you were thinking. If you are more comfortable reading english than code ( which some programmers are ) then it is much easier to wrap your head around what the point was. It’s also nice to come across when you are maintaining code that someone else wrote.
Restatements of well named objects are good for the reasons above; also the best named object still is an object name, whereas a good sentence is a good sentence regardless.
Comments with wanderlust are also helpful for making pointing out things along the way; like a rambling tour guide of sorts.
Finally, restatement of constants also helps explain what intention the programmer had for them. Honestly I can’t tell the difference between the good and bad; they both tell you how long the delay is supposed to be.
The others I definitely agree are useless.
Another rule of thumb: clear code, including well-thought-out identifiers, tells you *what* it does. Comments tell you *why* it does it.
I’m going to quibble slightly with point #3. It can be useful to have the “instant version history” of /recently/ commented-out code when making changes nearby. Wouldn’t it be cool if IDEs showed a recent-change history when you hover over a method or block?