As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
We all know that commenting our code is an important part of coding style for making our code understandable to the next person who comes along, or even ourselves in 6 months or so.
However, sometimes a comment just doesn't cut the mustard. I'm not talking about obvious jokes or vented frustraton, I'm talking about comments that appear to be making an attempt at explanation, but do it so poorly they might as well not be there. Comments that are too short, are too cryptic, or are just plain wrong.
As a cautonary tale, could you share something you've seen that was really just that bad, and if it's not obvious, show the code it was referring to and point out what's wrong with it? What should have gone in there instead?
See also:
When NOT to comment your code
How do you like your comments? (Best Practices)
What is the best comment in source code you have ever encountered?
Just the typical Comp Sci 101 type comments:
$i = 0; //set i to 0
$i++; //use sneaky trick to add 1 to i!
if ($i==$j) { // I made sure to use == rather than = here to avoid a bug
That sort of thing.
Unfilled javadoc boilerplate comments are particularly useless. They consume a lot of screen real estate without contributing anything useful. And the worst part is that where one such comment appears, hundreds of others are surely lurking behind.
/**
* Method declaration
*
*
* #param table
* #param row
*
* #throws SQLException
*/
void addTransactionDelete(Table table, Object row[]) throws SQLException {
I've found myself writing this little gem before:
//#TODO: Rewrite this, it sucks. Seriously.
Usually it's a good sign that I've reached the end of my coding session for the night.
// remember to comment code
wtf? :D
Something like this:
// This method takes two integer values and adds them together via the built-in
// .NET functionality. It would be possible to code the arithmetic function
// by hand, but since .NET provides it, that would be a waste of time
private int Add(int i, int j) // i is the first value, j is the second value
{
// add the numbers together using the .NET "+" operator
int z = i + j;
// return the value to the calling function
// return z;
// this code was updated to simplify the return statement, eliminating the need
// for a separate variable.
// this statement performs the add functionality using the + operator on the two
// parameter values, and then returns the result to the calling function
return i + j;
}
And so on.
Every comment that just repeats what the code says is useless. Comments should not tell me what the code does. If I don't know the programming language well enough, to understand what's going on by just reading the code, I should not be reading that code at all. Comments like
// Increase i by one
i++;
are completely useless. I see that i is increased by one, that is what the code says, I don't need a comment for that! Comments should be used to explain why something is done (in case it is far from being obvious) or why something is done that way and not any other way (so I can understand certain design decisions another programmer made that are by far not obvious at once). Further comments are useful to explain tricky code, where it is absolutely not possible to determine what's going on by having a quick look at the code (e.g. there are tricky algorithms to count the number of bits set in a number; if you don't know what this code does, you have no chance of guessing what goes on there).
Thread.Sleep(1000); // this will fix .NET's crappy threading implementation
I once worked on a project with a strange C compiler. It gave an error on a valid piece of code unless a comment was inserted between two statements. So I changed the comment to:
// Do not remove this comment else compilation will fail.
And it worked great.
I don't believe it. I came into this question after it had 22 answers, and no one pointed out the least possibly useful type of comment:
comments that are wrong.
It's bad enough that people write superfluous comments that get in the way of understanding code, but when someone writes a detailed comment explaining how something works, and it's either wrong in the first place, or wrong after the code was changed without changing the comment (much more likely scenario), that is definitely the worst kind of comment.
GhostDoc comes up with some pretty interesting ones on its own.
/// <summary>
/// Toes the foo.
/// </summary>
/// <returns></returns>
public Foo ToFoo()
// secret sauce
// Don't know why we have to do this
try
{
...some code...
}
catch
{
// Just don't crash, it wasn't that important anyway.
}
*sigh
Came across a file once. Thousands of lines of code, most of it quite horrendous. Badly named variables, tricky conditionals on loops and one comment buried in the middle of the file.
/* Hmmm. A bit tricky. */
//' OOOO oooo that smell!! Can't you smell that smell!??!??!!!!11!??/!!!!!1!!!!!!1
If Not Me.CurrentMenuItem.Parent Is Nothing Then
For Each childMenuItem As MenuItem In aMenuItem.Children
do something
Next
If Not Me.CurrentMenuItem.Parent.Parent Is Nothing Then
//'item is at least a grand child
For Each childMenuItem As MenuItem In aMenuItem.Children
For Each grandchildMenuItem As MenuItem In childMenuItem.Children
do something
Next
Next
If Not Me.CurrentMenuItem.Parent.Parent.Parent Is Nothing Then
//'item is at least a grand grand child
For Each childMenuItem As MenuItem In aMenuItem.Children
For Each grandchildMenuItem As MenuItem In childMenuItem.Children
For Each grandgrandchildMenuItem As MenuItem In grandchildMenuItem.Children
do something
Next
Next
Next
End If
End If
End If
Default comments inserted by IDEs.
The last project I worked on which used WebSphere Application Developer had plenty of maintenance developers and contractors who didn't seem to be bothered by the hundreds, if not thousands of Java classes which contained the likes of this:
/**
* #author SomeUserWhoShouldKnowBetter
*
* To change this generated comment edit the template variable "typecomment":
* Window>Preferences>Java>Templates.
* To enable and disable the creation of type comments go to
* Window>Preferences>Java>Code Generation.
*/
There was always that split-second between thinking you'd actually found a well-commented source file and realising that, yup, it's another default comment, which forced you to use SWEAR_WORD_OF_CHOICE.
I saw this comment yesterday in a C# app:
//TODO: Remove this comment.
My favorite all-time comment.
/* our second do loop */
do {
Whoever wrote it - you know who you are.
a very large database engine project in C many many years ago - thousands of lines of code with short and misspelled variable names, and no comments... until way deep in nested if-conditions several thousands of lines into the module the following comment appeared:
//if you get here then you really f**ked
by that time, i think we knew that already!
In a huge VB5 application
dim J
J = 0 'magic
J = J 'more magic
for J=1 to 100
...do stuff...
The reference is obviously THIS ... and yes, the application without those two lines fails at runtime with an unknown error code. We still don't know why.
Taken from one of my blog posts:
In the process of cleaning up some of the source code for one of the projects I manage, I came across the following comments:
/*
MAB 08-05-2004: Who wrote this routine? When did they do it? Who should
I call if I have questions about it? It's worth it to have a good header
here. It should helps to set context, it should identify the author
(hero or culprit!), including contact information, so that anyone who has
questions can call or email. It's useful to have the date noted, and a
brief statement of intention. On the other hand, this isn't meant to be
busy work; it's meant to make maintenance easier--so don't go overboard.
One other good reason to put your name on it: take credit! This is your
craft
*/
and then a little further down:
#include "xxxMsg.h" // xxx messages
/*
MAB 08-05-2004: With respect to the comment above, I gathered that
from the filename. I think I need either more or less here. For one
thing, xxxMsg.h is automatically generated from the .mc file. That might
be interesting information. Another thing is that xxxMsg.h should NOT be
added to source control, because it's auto-generated. Alternatively,
don't bother with a comment at all.
*/
and then yet again:
/*
MAB 08-05-2004: Defining a keyword?? This seems problemmatic [sic],
in principle if not in practice. Is this a common idiom?
*/
AHHHRRRGGHHH Just found this in some ancient code, bet the guy thought he was pretty funny
private
//PRIVATE means PRIVATE so no comments for you
function LoadIt(IntID: Integer): Integer;
The worst comment is one that gives a wrong explanation of what the code does.
That is worse than no comment at all.
I've seen this kind of thing in code with way too many comments (that shouldn't be there because the code is clear enough on its own), and it happens mostly when the code is updated (refactored, modified, etc.) but the comments aren't updated along with it.
A good rule of thumb is: only write comments to explain why code is doing something, not what it does.
Would definitely have to be comments that stand in place of error handling.
if(some_condition){
do_stuff();
}
else{
//An error occurred!
}
I just found this one, written on the line before a commented-out line of code:
//This causes a crash for some reason. I know the real reason but it doesn't fit on this line.
100k LOC application that was ported from vb6 to vb.net. It looks as though a previous developer had put a comment header on one method and then copied and pasted the exact comment onto every method he wrote from then on. Hundreds of methods and each one incorrectly commented...
When i first saw it i laughed... 6 months later the joke is wearing thin.
This is an absolutely real example from a database trigger:
/******************************************************************************
NAME: (repeat the trigger name)
PURPOSE: To perform work as each row is inserted or updated.
REVISIONS:
Ver Date Author Description
--------- ---------- --------------- ------------------------------------
1.0 27.6.2000 1. Created this trigger.
PARAMETERS:
INPUT:
OUTPUT:
RETURNED VALUE:
CALLED BY:
CALLS:
EXAMPLE USE:
ASSUMPTIONS:
LIMITATIONS:
ALGORITHM:
NOTES:
******************************************************************************/
/** function header comments required to pass checkstyle */
The two most unhelpful comments I've ever seen...
try
{
...
}
catch
{
// TODO: something catchy
}
I posted this one at the Daily WTF also, so I'll trim it to just the comment...
// TODO: The following if block should be reduced to one return statememt:
// return Regex.IsMatch(strTest, NAME_CHARS);
if (!Regex.IsMatch(strTest, NAME_CHARS))
return false;
else
return true;
One I've never found very helpful:
<!--- Lasciate ogne speranza, voi ch'intrate --->
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I'm wondering if people have a standard format for comments in their code. Not things like xml comments for a method or class but rather comments within a method.
See also:
Is there a standard (like phpdoc or python’s docstring) for commenting C# code?
You should really consider a couple things to make good comments beyond formatting.
Do not simply restate what the code is doing. For example,
// Start the services
StartServices();
is a frigging terrible comment!
Describe why. Why is the code doing what it's doing? What's the business assumption or algorithm step?
Format your comments for maximum readability. Tab them properly, leave spaces where necessary, etc.
If someone has already started commenting in a standard way, don't break that standard.
Check this article on MSDN about writing effective comments: http://msdn.microsoft.com/en-us/library/aa164797.aspx
// I usually write comments like this
Where I work it is required to use standard xml comment style for most of the declarations (classes, methods, some properties) (we use C#).
Sometimes you can see header/footer comments in use.
/****************************************************/
// Filename: Customer.cpp
// Created: John Doe
// Change history:
// 18.12.2008 / John Doe
// 14.01.2009 / Sara Smith
/****************************************************/
/* Here goes a lot of stuff */
/****************************************************/
// EOF: Customer.cpp
/****************************************************/
Something like this was used at one of my old places of work. In my opinion too much of unnecessary stuff. Change history is nicely seen these days through a version control system.
In many good software shops there are internal guidelines as to when and how to write comments. Documents are typically referred to as "Source code style policy" or something. It is very important to adhere to one common style in commenting the code.
Of course this commenting hype shouldn't go too far as to comment every little piece of code, especially the obvious ones.
/// <summary>
/// Handles the standard PageLoad event
/// </summary>
/// <param name="sender">
/// Event sender
/// </param>
/// <param name="e">
/// Event arguments
/// </param>
public void Page_Load (object sender, EventArgs e)
{
// Do something here
}
This one is a good example of over-obsession with commenting. Something like this adds exactly zero information but only adds noise to the source file. And we have to do it at work as required.
My personal opinion is add comments when you have something to say or explain, not just for the sake of commenting everything.
/**
* block comments to document a method for javadoc go like this
* #param
* #return
* #exception BTKException
* #see BTK
*/
Comment on the line above the code (block) that does what you're describing
// This is a comment.
Some code goes here
Avoid doing stuff like
// ----------------
// IMPORTANT COMMENT
// ----------------
And I avoid using the
/* comment */
And perhaps most importantly, clean up comments! A comment that describes non-existent functionality is worse than no comment at all.
//For one line, I write them like this
/*
For multiple lines of text
I write them like this
*/
/*
for(multiple lines of code){
I.WriteComents(With("//"));
Reason==If(I.Remove('The top begin-quote mark') then
I.Worry.Not('About removing the close-quote mark');
//*/
The problem with comments within a method (rather than in an interface), is that they are actually not meant to be seen by anyone except for people maintaining that method. Therefore, there is no real need for a standard for the comments. They don't get published anywhere, they're not publicly visible, callers will generally never see them.
In general, comments inside code should follow four rules:
They should not state the obvious
They should be consistent with what they describe
It should be clear what they describe (e.g., which line, block).
They should be readable by any future maintainer.
That being said, there is often a tendency to place information that is important to the callers as an internal comment. For example: "OOPS, This doesn't handle negative numbers". Whenever you see an internal comment, reconsider whether the header documentation should be updated, or use a tool that "pushes" the comments to the awareness of function callers (I have a tool like that for Java).
/* I will sometimes write
comments like this */
I can't believe we missed the REM keyword.
Though to be fair, it's for REMARK not COMMENT.
# ----------------------------------
# BIG IMPORTANT COMMENTS IN PERL/SH
# ----------------------------------
Comments standards are most useful when the comment will be parsed by an external tool (usualy, a document generator, like javadoc).
In this case, the external tool will state the standards.
For other cases, see How do you like your comments? (Best Practices)
//Cheap Debugger
//Response.Write(MySQLStringBecauseINeedToKnowWhatsBroken);
' I usually write comments like this
<!--How about comments like this!?-->
There are packages that will help write and format documentation. They require some specific changes so they can identify classes of comments.
such as doxygen:
http://www.doxygen.nl/manual/docblocks.html
/*! \brief Brief description.
* Brief description continued.
*
* Detailed description starts here.
*/
(* Modula-2 comments go like this *)
If you are paranoid and don't use or trust source control, you might do this
// Initials-YYMMDD-fixNo-Start
dosomething();
// Initials-YYMMDD-fixNo-Finish
It makes a bloody big mess, but it gives you some way to rollback changes.
But I'd suggest using source control
There can be religious wars on this subject.
What I try to do, that doesn't cause too much warfare, is
// explain the purpose of the following statement in functional terms
... some statement ...
The idea is, if I run the code through a program that deletes everything except the comments, what is left is pretty good pseudocode.
Something that's useful as a way to comment out code that you think you might need again is:
/*
... some code ...
/**/
then modify the first line - either delete it, or change it to /**/
/**/
... some code ...
/**/
/*
* Brief summary of what's going on.
*/
int code_that_goes_on(int c)
{
/* and then if I have to remark on something inside... */
return 0;
}
99% of compilers will support // comments, which is awesome, but that 1% still exists, and it's not too difficult to make life livable for them.
EDIT: The Delphi comment is a bit obtuse, but does point out a real deficiency. I intend this to be a C-specific answer.
I don't think there is a standard for what you are asking. And I don't see how it would add any benefit from /// comments on the method itself.
For creating documentation from your C# classes take a look at Sandcastle.
In C/C++/C#/Java, when I have a comment explaining a block of code:
// comment
code;
more_code;
when a comment is explaining a single line:
code; // comment
I usually use // for single sentence comments and /* ... */ comments for multi-sentence comments.
One comment style in C++/Java etc is this:
// Use // for all normal comments...
// and use multiline comments to comment out blocks of code while debugging:
/*
for(int i = 0; i < n; ++i) {
// If we only use // style comments in here,
// no comment here will mess up the block comment.
}
*/
I think it is an interesting point, even if it's not that incredibly useful.
My code is self-documenting. I need no comments.
I'm surprised that not more people recommended doxygen. It is a good way of documenting code, with the side effect that it can automagically generate html + pdf API documentation at the end of the day.
I prefer commenting this way for function
/**
* Activates user if not already activated
* #param POST string verificationCode
* #param POST string key
* #return true on success, false on failure
* #author RN Kushwaha <rn.kuswaha#gmail.com>
* #since v1.0 <date: 10th June 2015>
*/
public function activateUserAccount() {
//some code here
}
I use single line comment for code descriptions like
//check if verificationCode exists in any row of user table
code here
You might want to at least consider using standard comment formats for the PHP Reflection Class: https://www.php.net/manual/en/reflectionclass.getdoccomment.php
My sites compress html so a comment like
// comment here
in JS will crash the java script.
The specs for using // in PHP is only supposed to be a "short comment" ie: one line. Personally I don't think they should be used for more than one line.
Using them also makes it impossible to compress - or a lot harder to compress than what it should be.
Lastly.
Human interpretation is NOT absolute - a computer code is :)
So if you have a code that needs to or should be read - (Go Nasty) and don't comment it. ie: Force the reader to read the code rather than you relying on their interpretation of your comment.
Most programmers will have had the experience of debugging/fixing someone else's code. Sometimes that "someone else's code" is so obfuscated it's bad enough trying to understand what it's doing.
What's the worst (most obfuscated) code you've had to debug/fix?
If you didn't throw it away and recode it from scratch, well why didn't you?
PHP OSCommerce is enough to say, it is obfuscated code...
a Java class
only static methods that manipulates DOM
8000 LOCs
long chain of methods that return null on "error": a.b().c().d().e()
very long methods (400/500 LOC each)
nested if, while, like:
if (...) {
for (...) {
if (...) {
if (...) {
while (...) {
if (...) {
cut-and-paste oriented programming
no exceptions, all exceptions are catched and "handled" using printStackTrace()
no unit tests
no documentation
I was tempted to throw away and recode... but, after 3 days of hard debugging,
I've added the magic if :-)
Spaghetti code PHP CMS system.
by default, programmers think someone else's code is obfuscated.
The worse I probably had to do was interpreting what variables i1, i2 j, k, t were in a simple method and they were not counters in 'for' loops.
In all other circumstances I guess the problem area was difficult which made the code look difficult.
I found this line in our codebase today and thought it was a nice example of sneaky obfuscation:
if (MULTICLICK_ENABLED.equals(propService.getProperty(PropertyNames.MULTICLICK_ENABLED))) {} else {
return false;
}
Just making sure I read the whole line. NO SKIMREADING.
When working on a GWT project, I would reach parts of GWT-compiled obfuscated JS code which wasn't mine.
Now good luck debugging real obfuscated code.
I can't remember the full code, but a single part of it remains burned into my memory as something I spend hours trying to understand:
do{
$tmp = shift unless shift;
$tmp;
}while($tmp);
I couldn't understand it at first, it looks so useless, then I printed out #_ for a list of arguments, a series of alternating boolean and function names, the code was used in conjunction with a library detection module that changed behaviour if a function was broken, but the code was so badly documented and made of things like that which made no sense without a complete understanding of the full code I gave up and rewrote the whole thing.
UPDATE from DVK:
And, lest someone claims this was because Perl is unreadable as opposed to coder being a golf master instead of good software developer, here's the same code in a slightly less obfuscated form (the really correct code wouldn't even HAVE alternating sub names and booleans in the first place :)
# This subroutine take a list of alternating true/false flags
# and subroutine names; and executes the named subroutines for which flag is true.
# I am also weird, otherwise I'd have simply have passed list of subroutines to execute :)
my #flags_and_sub_names_list = #_;
while ( #flags_and_sub_names_list ) {
my $flag = shift #flags_and_sub_names_list;
my $subName = shift #flags_and_sub_names_list;
next unless $flag && $subName;
&{ $subName }; # Call the named subroutine
}
I've had a case of a 300lines function performing input sanitization which missed a certain corner case. It was parsing certain situations manually using IndexOf and Substring plus a lot of inlined variables and constants (looks like the original coder didn't know anything about good practices), and no comment was provided. Throwing it away wasn't feasible due to time constraints and the fact that I didn't have the specification required so rewriting it would've meant understanding the original, but after understanding it fixing it was just quicker. I also added lots of comments, so whoever shall come after me won't feel the same pain taking a look at it...
The Perl statement:
select((select(s),$|=1)[0])
which, at the suggestion of the original author (Randal Schwartz himself, who said he disliked it but nothing else was available at the time), was replaced with something a little more understandable:
IO::Handle->autoflush
Beyond that one-liner, some of the Java JDBC libraries from IBM are obfuscated and all variables and functions are either combinations of the letter 'l' and '1' or single/double characters - very hard to track anything down until you get them all renamed. Needed to do this to track down why they worked fine in IBM's JRE but not Sun's.
If you're talking about HLL codes, once I was updating project written by a chinese and all comments were chinese (stored in ansii) and it was a horror to understand some code fragments, if you're talking about low level code there were MANY of them (obfuscated, mutated, vm-ed...).
I once had to reverse engineer a Java 1.1 framework that:
Extended event-driven SAX parser classes for every class, even those that didn't parse XML (the overridden methods were simply invoked ad hoc by other code)
Custom runtime exceptions were thrown in lieu of method invocations wherever possible. As a result, most of the business logic landed in a nested series of catch blocks.
If I had to guess, it was probably someone's "smart" idea that method invocations were expensive in Java 1.1, so throwing exceptions for non-exceptional flow control was somehow considered an optimization.
Went through about three bottles of eye drops.
I once found a time bomb that had been intentionally obfuscated.
When I had finally decoded what it was doing I mentioned it to the manager who said they knew about the time bomb but had left it in place because it was so ineffective and was interwoven with other code.
The time bomb was (presumably) supposed to go off after a certain date.
Instead, it had a bug in it so it only activated if someone was working after lunchtime on Dec 31st.
It had taken three years for that circumstance to occur since the guy who wrote the time bomb left the company.
Duplicate
What are your hard rules about commenting?
A Developer I work with had some things to say about commenting that were interesting to me (see below). What is your personal approach/take on commenting?
"I don't add comments to code unless
its a simple heading or there's a
platform-bug or a necessary
work-around that isn't obvious. Code
can change and comments may become
misleading. Code should be
self-documenting in its use of
descriptive names and its logical
organization - and its solutions
should be the cleanest/simplest way
to perform a given task. If a
programmer can't tell what a program
does by only reading the code, then
he's not ready to alter it.
Commenting tends to be a crutch for
writing something complex or
non-obvious - my goal is to always
write clean and simple code."
"I think there a few camps when it
comes to commenting, the
enterprisey-type who think they're
writing an API and some grand
code-library that will be used for
generations to come, the
craftsman-like programmer that thinks
code says what it does clearer than a
comment could, and novices that write
verbose/unclear code so as to need to
leave notes to themselves as to why
they did something."
There's a tragic flaw with the "self-documenting code" theory. Yes, reading the code will tell you exactly what it is doing. However, the code is incapable of telling you what it's supposed to be doing.
I think it's safe to say that all bugs are caused when code is not doing what it's supposed to be doing :). So if we add some key comments to provide maintainers with enough information to know what a piece of code is supposed to be doing, then we have given them the ability to fix a whole lot of bugs.
That leaves us with the question of how many comments to put in. If you put in too many comments, things become tedious to maintain and the comments will inevitably be out of date with the code. If you put in too few, then they're not particularly useful.
I've found regular comments to be most useful in the following places:
1) A brief description at the top of a .h or .cpp file for a class explaining the purpose of the class. This helps give maintainers a quick overview without having to sift through all of the code.
2) A comment block before the implementation of a non-trivial function explaining the purpose of it and detailing its expected inputs, potential outputs, and any oddities to expect when calling the function. This saves future maintainers from having to decipher entire functions to figure these things out.
Other than that, I tend to comment anything that might appear confusing or odd to someone. For example: "This array is 1 based instead of 0 based because of blah blah".
Well written, well placed comments are invaluable. Bad comments are often worse than no comments. To me, lack of any comments at all indicates laziness and/or arrogance on the part of the author of the code. No matter how obvious it is to you what the code is doing or how fantastic your code is, it's a challenging task to come into a body of code cold and figure out what the heck is going on. Well done comments can make a world of difference getting someone up to speed on existing code.
I've always liked Refactoring's take on commenting:
The reason we mention comments here is that comments often are used as a deodorant. It's surprising how often you look at thickly commented code and notice that the comments are there because the code is bad.
Comments lead us to bad code that has all the rotten whiffs we've discussed in the rest of this chapter. Our first action is to remove the bad smells by refactoring. When we're finished, we often find that the comments are superfluous.
As controversial as that is, it's rings true for the code I've read. To be fair, Fowler isn't saying to never comment, but to think about the state of your code before you do.
You need documentation (in some form; not always comments) for a local understanding of the code. Code by itself tells you what it does, if you read all of it and can keep it all in mind. (More on this below.) Comments are best for informal or semiformal documentation.
Many people say comments are a code smell, replaceable by refactoring, better naming, and tests. While this is true of bad comments (which are legion), it's easy to jump to concluding it's always so, and hallelujah, no more comments. This puts all the burden of local documentation -- too much of it, I think -- on naming and tests.
Document the contract of each function and, for each type of object, what it represents and any constraints on a valid representation (technically, the abstraction function and representation invariant). Use executable, testable documentation where practical (doctests, unit tests, assertions), but also write short comments giving the gist where helpful. (Where tests take the form of examples, they're incomplete; where they're complete, precise contracts, they can be as much work to grok as the code itself.) Write top-level comments for each module and each project; these can explain conventions that keep all your other comments (and code) short. (This supports naming-as-documentation: with conventions established, and a place we can expect to find subtleties noted, we can be confident more often that the names tell all we need to know.) Longer, stylized, irritatingly redundant Javadocs have their uses, but helped generate the backlash.
(For instance, this:
Perform an n-fold frobulation.
#param n the number of times to frobulate
#param x the x-coordinate of the center of frobulation
#param y the y-coordinate of the center of frobulation
#param z the z-coordinate of the center of frobulation
could be like "Frobulate n times around the center (x,y,z)." Comments don't have to be a chore to read and write.)
I don't always do as I say here; it depends on how much I value the code and who I expect to read it. But learning how to write this way made me a better programmer even when cutting corners.
Back on the claim that we document for the sake of local understanding: what does this function do?
def is_even(n): return is_odd(n-1)
Tests if an integer is even? If is_odd() tests if an integer is odd, then yes, that works. Suppose we had this:
def is_odd(n): return is_even(n-1)
The same reasoning says this is_odd() tests if an integer is odd. Put them together, of course, and neither works, even though each works if the other does. Change it a bit and we'd have code that does work, but only for natural numbers, while still locally looking like it works for integers. In microcosm that's what understanding a codebase is like: tracing dependencies around in circles to try to reverse-engineer assumptions the author could have explained in a line or two if they'd bothered. I hate the expense of spirit thoughtless coders have put me to this way over the past couple of decades: oh, this method looks like it has the side effect of farbuttling the warpcore... always? Well, if odd crobuncles desaturate, at least; do they? Better check all the crobuncle-handling code... which will pose its own challenges to understanding. Good documentation cuts this O(n) pointer-chasing down to O(1): e.g. knowing a function's contract and the contracts of the things it explicitly uses, the function's code should make sense with no further knowledge of the system. (Here, contracts saying is_even() and is_odd() work on natural numbers would tell us that both functions need to test for n==0.)
My only real rule is that comments should explain why code is there, not what it is doing or how it is doing it. Those things can change, and if they do the comments have to be maintained. The purpose the code exists in the first place shouldn't change.
the purpose of comments is to explain the context - the reason for the code; this, the programmer cannot know from mere code inspection. For example:
strangeSingleton.MoveLeft(1.06);
badlyNamedGroup.Ignite();
who knows what the heck this is for? but with a simple comment, all is revealed:
//when under attack, sidestep and retaliate with rocket bundles
strangeSingleton.MoveLeft(1.06);
badlyNamedGroup.Ignite();
seriously, comments are for the why, not the how, unless the how is unintuitive.
While I agree that code should be self-readable, I still see a lot of value in adding extensive comment blocks for explaining design decisions. For example "I did xyz instead of the common practice of abc because of this caveot ..." with a URL to a bug report or something.
I try to look at it as: If I'm dead and gone and someone straight out of college has to fix a bug here, what are they going to need to know?
In general I see comments used to explain poorly written code. Most code can be written in a way that would make comments redundant. Having said that I find myself leaving comments in code where the semantics aren't intuitive, such as calling into an API that has strange or unexpected behavior etc...
I also generally subscribe to the self-documenting code idea, so I think your developer friend gives good advice, and I won't repeat that, but there are definitely many situations where comments are necessary.
A lot of times I think it boils down to how close the implementation is to the types of ordinary or easy abstractions that code-readers in the future are going to be comfortable with or more generally to what degree the code tells the entire story. This will result in more or fewer comments depending on the type of programming language and project.
So, for example if you were using some kind of C-style pointer arithmetic in an unsafe C# code block, you shouldn't expect C# programmers to easily switch from C# code reading (which is probably typically more declarative or at least less about lower-level pointer manipulation) to be able to understand what your unsafe code is doing.
Another example is when you need to do some work deriving or researching an algorithm or equation or something that is not going to end up in your code but will be necessary to understand if anyone needs to modify your code significantly. You should document this somewhere and having at least a reference directly in the relevant code section will help a lot.
I don't think it matters how many or how few comments your code contains. If your code contains comments, they have to maintained, just like the rest of your code.
EDIT: That sounded a bit pompous, but I think that too many people forget that even the names of the variables, or the structures we use in the code, are all simply "tags" - they only have meaning to us, because our brains see a string of characters such as customerNumber and understand that it is a customer number. And while it's true that comments lack any "enforcement" by the compiler, they aren't so far removed. They are meant to convey meaning to another person, a human programmer that is reading the text of the program.
If the code is not clear without comments, first make the code a clearer statement of intent, then only add comments as needed.
Comments have their place, but primarily for cases where the code is unavoidably subtle or complex (inherent complexity is due to the nature of the problem being solved, not due to laziness or muddled thinking on the part of the programmer).
Requiring comments and "measuring productivity" in lines-of-code can lead to junk such as:
/*****
*
* Increase the value of variable i,
* but only up to the value of variable j.
*
*****/
if (i < j) {
++i;
} else {
i = j;
}
rather than the succinct (and clear to the appropriately-skilled programmer):
i = Math.min(j, i + 1);
YMMV
The vast majority of my commnets are at the class-level and method-level, and I like to describe the higher-level view instead of just args/return value. I'm especially careful to describe any "non-linearities" in the function (limits, corner cases, etc) that could trip up the unwary.
Typically I don't comment inside a method, except to mark "FIXME" items, or very occasionally some sort of "here be monsters" gotcha that I just can't seem to clean up, but I work very hard to avoid those. As Fowler says in Refactoring, comments tend to indicate smally code.
Comments are part of code, just like functions, variables and everything else - and if changing the related functionality the comment must also be updated (just like function calls need changing if function arguments change).
In general, when programming you should do things once in one place only.
Therefore, if what code does is explained by clear naming, no comment is needed - and this is of course always the goal - it's the cleanest and simplest way.
However, if further explanation is needed, I will add a comment, prefixed with INFO, NOTE, and similar...
An INFO: comment is for general information if someone is unfamiliar with this area.
A NOTE: comment is to alert of a potential oddity, such as a strange business rule / implementation.
If I specifically don't want people touching code, I might add a WARNING: or similar prefix.
What I don't use, and am specifically opposed to, are changelog-style comments - whether inline or at the head of the file - these comments belong in the version control software, not the sourcecode!
I prefer to use "Hansel and Gretel" type comments; little notes in the code as to why I'm doing it this way, or why some other way isn't appropriate. The next person to visit this code will probably need this info, and more often than not, that person will be me.
As a contractor I know that some people maintaining my code will be unfamiliar with the advanced features of ADO.Net I am using. Where appropriate, I add a brief comment about the intent of my code and a URL to an MSDN page that explains in more detail.
I remember learning C# and reading other people's code I was often frustrated by questions like, "which of the 9 meanings of the colon character does this one mean?" If you don't know the name of the feature, how do you look it up?! (Side note: This would be a good IDE feature: I select an operator or other token in the code, right click then shows me it's language part and feature name. C# needs this, VB less so.)
As for the "I don't comment my code because it is so clear and clean" crowd, I find sometimes they overestimate how clear their very clever code is. The thought that a complex algorithm is self-explanatory to someone other than the author is wishful thinking.
And I like #17 of 26's comment (empahsis added):
... reading the code will tell you exactly
what it is doing. However, the code is
incapable of telling you what it's
supposed to be doing.
I very very rarely comment. MY theory is if you have to comment it's because you're not doing things the best way possible. Like a "work around" is the only thing I would comment. Because they often don't make sense but there is a reason you are doing it so you need to explain.
Comments are a symptom of sub-par code IMO. I'm a firm believer in self documenting code. Most of my work can be easily translated, even by a layman, because of descriptive variable names, simple form, and accurate and many methods (IOW not having methods that do 5 different things).
Comments are part of a programmers toolbox and can be used and abused alike. It's not up to you, that other programmer, or anyone really to tell you that one tool is bad overall. There are places and times for everything, including comments.
I agree with most of what's been said here though, that code should be written so clear that it is self-descriptive and thus comments aren't needed, but sometimes that conflicts with the best/optimal implementation, although that could probably be solved with an appropriately named method.
I agree with the self-documenting code theory, if I can't tell what a peice of code is doing simply by reading it then it probably needs refactoring, however there are some exceptions to this, I'll add a comment if:
I'm doing something that you don't
normally see
There are major side effects or implementation details that aren't obvious, or won't be next year
I need to remember to implement
something although I prefer an
exception in these cases.
If I'm forced to go do something else and I'm having good ideas, or a difficult time with the code, then I'll add sufficient comments to tmporarily preserve my mental state
Most of the time I find that the best comment is the function or method name I am currently coding in. All other comments (except for the reasons your friend mentioned - I agree with them) feel superfluous.
So in this instance commenting feels like overkill:
/*
* this function adds two integers
*/
int add(int x, int y)
{
// add x to y and return it
return x + y;
}
because the code is self-describing. There is no need to comment this kind of thing as the name of the function clearly indicates what it does and the return statement is pretty clear as well. You would be surprised how clear your code becomes when you break it down into tiny functions like this.
When programming in C, I'll use multi-line comments in header files to describe the API, eg parameters and return value of functions, configuration macros etc...
In source files, I'll stick to single-line comments which explain the purpose of non-self-evident pieces of code or to sub-section a function which can't be refactored to smaller ones in a sane way. Here's an example of my style of commenting in source files.
If you ever need more than a few lines of comments to explain what a given piece of code does, you should seriously consider if what you're doing can't be done in a better way...
I write comments that describe the purpose of a function or method and the results it returns in adequate detail. I don't write many inline code comments because I believe my function and variable naming to be adequate to understand what is going on.
I develop on a lot of legacy PHP systems that are absolutely terribly written. I wish the original developer would have left some type of comments in the code to describe what was going on in those systems. If you're going to write indecipherable or bad code that someone else will read eventually, you should comment it.
Also, if I am doing something a particular way that doesn't look right at first glance, but I know it is because the code in question is a workaround for a platform or something like that, then I'll comment with a WARNING comment.
Sometimes code does exactly what it needs to do, but is kind of complicated and wouldn't be immediately obvious the first time someone else looked at it. In this case, I'll add a short inline comment describing what the code is intended to do.
I also try to give methods and classes documentation headers, which is good for intellisense and auto-generated documentation. I actually have a bad habit of leaving 90% of my methods and classes undocumented. You don't have time to document things when you're in the middle of coding and everything is changing constantly. Then when you're done you don't feel like going back and finding all the new stuff and documenting it. It's probably good to go back every month or so and just write a bunch of documentation.
Here's my view (based on several years of doctoral research):
There's a huge difference between commenting functions (sort of a black box use, like JavaDocs), and commenting actual code for someone who will read the code ("internal commenting").
Most "well written" code shouldn't require much "internal commenting" because if it performs a lot then it should be broken into enough function calls. The functionality for each of these calls is then captured in the function name and in the function comments.
Now, function comments are indeed the problem, and in some ways your friend is right, that for most code there is no economical incentive for complete specifications the way that popular APIs are documented. The important thing here is to identify what are the "directives": directives are those information pieces that directly affect clients, and require some direct action (and are often unexpected). For example, X must be invoked before Y, don't call this from outside a UI thread, be aware that this has a certain side effect, etc. These are the things that are really important to capture.
Since most people never read full function documentations, and skim what they do read, you can actually increase the chances of awareness by capturing only the directives rather than the whole description.
I comment as much as needed - then, as much as I will need it a year later.
We add comments which provide the API reference documentation for all public classes / methods / properties / etc... This is well worth the effort because XML Documentation in C# has the nice effect of providing IntelliSense to users of these public APIs. .NET 4.0's code contracts will enable us to improve further on this practice.
As a general rule, we do not document internal implementations as we write code unless we are doing something non-obvious. The theory is that while we are writing new implementations, things are changing and comments are more likely than not to be wrong when the dust settles.
When we go back in to work on an existing piece of code, we add comments when we realize that it's taking some thought to figure out what in the heck is going on. This way, we wind up with comments where they are more likely to be correct (because the code is more stable) and where they are more likely to be useful (if I'm coming back to a piece of code today, it seems more likely that I might come back to it again tomorrow).
My approach:
Comments bridge the gap between context / real world and code. Therefore, each and every single line is commented, in correct English language.
I DO reject code that doesn't observe this rule in the strictest possible sense.
Usage of well formatted XML - comments is self-evident.
Sloppy commenting means sloppy code!
Here's how I wrote code:
if (hotel.isFull()) {
print("We're fully booked");
} else {
Guest guest = promptGuest();
hotel.checkIn(guest);
}
here's a few comments that I might write for that code:
// if hotel is full, refuse checkin, otherwise
// prompt the user for the guest info, and check in the guest.
If your code reads like a prose, there is no sense in writing comments that simply repeats what the code reads since the mental processing needed for reading the code and the comments would be almost equal; and if you read the comments first, you will still need to read the code as well.
On the other hand, there are situations where it is impossible or extremely difficult to make the code looks like a prose; that's where comment could patch in.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
When I asked this question I got almost always a definite yes you should have coding standards.
What was the strangest coding standard rule that you were ever forced to follow?
And by strangest I mean funniest, or worst, or just plain odd.
In each answer, please mention which language, what your team size was, and which ill effects it caused you and your team.
I hate it when the use of multiple returns is banned.
reverse indentation. For example:
for(int i = 0; i < 10; i++)
{
myFunc();
}
and:
if(something)
{
// do A
}
else
{
// do B
}
Maybe not the most outlandish one you'll get, but I really really hate when I have to preface database table names with 'tbl'
Almost any kind of hungarian notation.
The problem with hungarian notation is that it is very often misunderstood. The original idea was to prefix the variable so that the meaning was clear. For example:
int appCount = 0; // Number of apples.
int pearCount = 0; // Number of pears.
But most people use it to determine the type.
int iAppleCount = 0; // Number of apples.
int iPearCount = 0; // Number of pears.
This is confusing, because although both numbers are integers, everybody knows, you can't compare apples with pears.
No ternary operator allowed where I currently work:
int value = (a < b) ? a : b;
... because not everyone "gets it". If you told me, "Don't use it because we've had to rewrite them when the structures get too complicated" (nested ternary operators, anyone?), then I'd understand. But when you tell me that some developers don't understand them... um... Sure.
To NEVER remove any code when making changes. We were told to comment all changes. Bear in mind we use source control. This policy didn't last long because developers were in an uproar about it and how it would make the code unreadable.
I once worked under the tyranny of the Mighty VB King.
The VB King was the pure master of MS Excel and VBA, as well as databases (Hence his surname : He played with Excel while the developers worked with compilers, and challenging him on databases could have detrimental effects on your career...).
Of course, his immense skills gave him an unique vision of development problems and project management solutions: While not exactly coding standards in the strictest sense, the VB King regularly had new ideas about "coding standards" and "best practices" he tried (and oftentimes succeeded) to impose on us. For example:
All C/C++ arrays shall start at index 1, instead of 0. Indeed, the use of 0 as first index of an array is obsolete, and has been superseded by Visual Basic 6's insightful array index management.
All functions shall return an error code: There are no exceptions in VB6, so why would we need them at all? (i.e. in C++)
Since "All functions shall return an error code" is not practical for functions returning meaningful types, all functions shall have an error code as first [in/out] parameter.
All our code will check the error codes (this led to the worst case of VBScript if-indentation I ever saw in my career... Of course, as the "else" clauses were never handled, no error was actually found until too late).
Since we're working with C++/COM, starting this very day, we will code all our DOM utility functions in Visual Basic.
ASP 115 errors are evil. For this reason, we will use On Error Resume Next in our VBScript/ASP code to avoid them.
XSL-T is an object oriented language. Use inheritance to resolve your problems (dumb surprise almost broke my jaw open this one day).
Exceptions are not used, and thus should be removed. For this reason, we will uncheck the checkbox asking for destructor call in case of exception unwinding (it took days for an expert to find the cause of all those memory leaks, and he almost went berserk when he found out they had willingly ignored (and hidden) his technical note about checking the option again, sent handfuls of weeks before).
catch all exceptions in the COM interface of our COM modules, and dispose them silently (this way, instead of crashing, a module would only appear to be faster... Shiny!... As we used the über error handling described above, it even took us some time to understand what was really happening... You can't have both speed and correct results, can you?).
Starting today, our code base will split into four branches. We will manage their synchronization and integrate all bug corrections/evolutions by hand.
All but the C/C++ arrays, VB DOM utility functions and XSL-T as OOP language were implemented despite our protests. Of course, over the time, some were discovered, ahem, broken, and abandoned altogether.
Of course, the VB King credibility never suffered for that: Among the higher management, he remained a "top gun" technical expert...
This produced some amusing side effects, as you can see by following the link What is the best comment in source code you have ever encountered?
Back in the 80's/90's, I worked for an aircraft simulator company that used FORTRAN. Our FORTRAN compiler had a limit of 8 characters for variable names. The company's coding standards reserved the first three of them for Hungarian-notation style info. So we had to try and create meaningful variable names with just 5 characters!
I worked at a place that had a merger between 2 companies. The 'dominant' one had a major server written in K&R C (i.e. pre-ANSI). They forced the Java teams (from both offices -- probably 20 devs total) to use this format, which gleefully ignored the 2 pillars of the "brace debate" and goes straight to crazy:
if ( x == y )
{
System.out.println("this is painful");
x = 0;
y++;
}
Forbidden:
while (true) {
Allowed:
for (;;) {
a friend of mine - we'll call him CodeMonkey - got his first job out of college [many years ago] doing in-house development in COBOL. His first program was rejected as 'not complying with our standards' because it used... [shudder!] nested IF statements
the coding standards banned the use of nested IF statements
now, CodeMonkey was not shy and was certain of his abilities, so he persisted in asking everyone up the chain and down the aisle why this rule existed. Most claimed they did not know, some made up stuff about 'readability', and finally one person remembered the original reason: the first version of the COBOL compiler they used had a bug and didn't handle nested IF statements correctly.
This compiler bug, of course, had been fixed for at least a decade, but no one had challenged the standards. [baaa!]
CodeMonkey was successful in getting the standards changed - eventually!
Once worked on a project where underscores were banned. And I mean totally banned. So in a c# winforms app, whenever we added a new event handler (e.g. for a button) we'd have to rename the default method name from buttonName_Click() to something else, just to satisfy the ego of the guy that wrote the coding standards. To this day I don't know what he had against the humble underscore
Totally useless database naming conventions.
Every table name has to start with a number. The numbers show which kind of data is in the table.
0: data that is used everywhere
1: data that is used by a certain module only
2: lookup table
3: calendar, chat and mail
4: logging
This makes it hard to find a table if you only know the first letter of its name.
Also - as this is a mssql database - we have to surround tablenames with square brackets everywhere.
-- doesn't work
select * from 0examples;
-- does work
select * from [0examples];
We were doing a C++ project and the team lead was a Pascal guy.
So we had a coding standard include file to redefine all that pesky C and C++ syntax:
#define BEGIN {
#define END }
but wait there's more!
#define ENDIF }
#define CASE switch
etc. It's hard to remember after all this time.
This took what would have been perfectly readable C++ code and made it illegible to anyone except the team lead.
We also had to use reverse Hungarian notation, i.e.
MyClass *class_pt // pt = pointer to type
UINT32 maxHops_u // u = uint32
although oddly I grew to like this.
At a former job:
"Normal" tables begin with T_
"System" tables (usually lookups) begin with TS_ (except when they don't because somebody didn't feel like it that day)
Cross-reference tables begin with TSX_
All field names begin with F_
Yes, that's right. All of the fields, in every single table. So that we can tell it's a field.
A buddy of mine encountered this rule while working at a government job. The use of ++ (pre or post) was completely banned. The reason: Different compilers might interpret it differently.
Half of the team favored four-space indentation; the other half favored two-space indentation.
As you can guess, the coding standard mandated three, so as to "offend all equally" (a direct quote).
Not being able to use Reflection as the manager claimed it involved too much 'magic'.
The very strangest one I had, and one which took me quite some time to overthrow, was when the owner of our company demanded that our new product be IE only. If it could work on FireFox, that was OK, but it had to be IE only.
This might not sound too strange, except for one little flaw. All of the software was for a bespoke server software package, running on Linux, and all client boxes that our customer was buying were Linux. Short of trying to figure out how to get Wine (in those days, very unreliable) up and running on all of these boxes and seeing if we could get IE running and training their admins how to debug Wine problems, it simply wasn't possible to meet the owner's request. The problem was that he was doing the Web design and simply didn't know how to make Web sites compliant with FireFox.
It probably won't shock you to know that that our company went bankrupt.
Using generic numbered identifier names
At my current work we have two rules which are really mean:
Rule 1: Every time we create a new field in a database table we have to add additional reserve fields for future use. These reserve fields are numbered (because no one knows which data they will hold some day) The next time we need a new field we first look for an unused reserve field.
So we end up with with customer.reserve_field_14 containing the e-mail address of the customer.
At one day our boss thought about introducing reserve tables, but fortunatly we could convince him not to do it.
Rule 2: One of our products is written in VB6 and VB6 has a limit of the total count of different identifier names and since the code is very large, we constantly run into this limit. As a "solution" all local variable names are numbered:
Lvarlong1
Lvarlong2
Lvarstr1
...
Although that effectively circumvents the identifier limit, these two rules combined lead to beautiful code like this:
...
If Lvarbool1 Then
Lvarbool2 = True
End If
If Lvarbool2 Or Lvarstr1 <> Lvarstr5 Then
db.Execute("DELETE FROM customer WHERE " _
& "reserve_field_12 = '" & Lvarstr1 & "'")
End If
...
You can imagine how hard it is to fix old or someone else's code...
Latest update: Now we are also using "reserve procedures" for private members:
Private Sub LSub1(Lvarlong1 As Long, Lvarstr1 As String)
If Lvarlong1 >= 0 Then
Lvarbool1 = LFunc1(Lvarstr1)
Else
Lvarbool1 = LFunc6()
End If
If Lvarbool1 Then
LSub4 Lvarstr1
End If
End Sub
EDIT: It seems that this code pattern is becoming more and more popular. See this The Daily WTF post to learn more: Astigmatism :)
Back in my C++ days we were not allowed to use ==,>=, <=,&&, etc. there were macros for this ...
if (bob EQ 7 AND alice LEQ 10)
{
// blah
}
this was obviously to deal with the "old accidental assignment in conditional bug", however we also had the rule "put constants before variables", so
if (NULL EQ ptr); //ok
if (ptr EQ NULL); //not ok
Just remembered, the simplest coding standard I ever heard was "Write code as if the next maintainer is a vicious psychopath who knows where you live."
Hungarian notation in general.
I've had a lot of stupid rules, but not a lot that I considered downright strange.
The sillyiest was on a NASA job I worked back in the early 90's. This was a huge job, with well over 100 developers on it. The experienced developers who wrote the coding standards decided that every source file should begin with a four letter acronym, and the first letter had to stand for the group that was responsible for the file. This was probably a great idea for the old FORTRAN 77 projects they were used to.
However, this was an Ada project, with a nice hierarchal library structure, so it made no sense at all. Every directory was full of files starting with the same letter, followed by 3 more nonsense leters, an underscore, and then part of the file name that mattered. All the Ada packages had to start with this same five-character wart. Ada "use" clauses were not allowed either (arguably a good thing under normal circumstances), so that meant any reference to any identifier that wasn't local to that source file also had to include this useless wart. There probably should have been an insurrection over this, but the entire project was staffed by junior programmers and fresh from college new hires (myself being the latter).
A typical assignment statement (already verbose in Ada) would end up looking something like this:
NABC_The_Package_Name.X := NABC_The_Package_Name.X +
CXYZ_Some_Other_Package_Name.Delta_X;
Fortunately they were at least enlightened enough to allow us more than 80 columns! Still, the facility wart was hated enough that it became boilerplate code at the top of everyone's source files to use Ada "renames" to get rid of the wart. There'd be one rename for each imported ("withed") package. Like this:
package Package_Name renames NABC_Package_Name;
package Some_Other_Package_Name renames CXYZ_Some_Other_Package_Name;
--// Repeated in this vein for an average of 10 lines or so
What the more creative among us took to doing was trying to use the wart to make an acutally sensible (or silly) package name. (I know what you are thinking, but explitives were not allowed and shame on you! That's disgusting). For example, I was in the Common code group, and I needed to make a package to interface with the Workstation group. After a brainstorming session with the Workstation guy, we decided to name our packages so that someone needing both would have to write:
with CANT_Interface_Package;
with WONT_Interface_Package;
When I started working at one place, and started entering my code into the source control, my boss suddenly came up to me, and asked me to stop committing so much. He told me it is discouraged to do more than 1 commit per-day for a developer because it litters the source control. I simply gaped at him...
Later I understood that the reason he even came up to me about it is because the SVN server would send him (and 10 more high executives) a mail for each commit someone makes. And by littering the source control I guessed he ment his mailbox.
Doing all database queries via stored procedures in Sql Server 2000. From complex multi-table queries to simple ones like:
select id, name from people
The arguments in favor of procedures were:
Performance
Security
Maintainability
I know that the procedure topic is quite controversial, so feel free to score my answer negatively ;)
There must be 165 unit tests (not necessarily automated) per 1000 lines of code. That works out at one test for roughly every 8 lines.
Needless to say, some of the lines of code are quite long, and functions return this pointers to allow chaining.
We had to sort all the functions in classes alphabetically, to make them "easier to find".
Never mind the ide had a drop down. That was too many clicks.
(same tech lead wrote an app to remove all comments from our source code).
In 1987 or so, I took a job with a company that hired me because I was one of a small handful of people who knew how to use Revelation. Revelation, if you've never heard of it, was essentially a PC-based implementation of the Pick operating system - which, if you've never heard of it, got its name from its inventor, the fabulously-named Dick Pick. Much can be said about the Pick OS, most of it good. A number of supermini vendors (Prime and MIPS, at least) used Pick, or their own custom implementations of it.
This company was a Prime shop, and for their in-house systems they used Information. (No, that was really its name: it was Prime's implementation of Pick.) They had a contract with the state to build a PC-based system, and had put about a year into their Revelation project before the guy doing all the work, who was also their MIS director, decided he couldn't do both jobs anymore and hired me.
At any rate, he'd established a number of coding standards for their Prime-based software, many of which derived from two basic conditions: 1) the use of 80-column dumb terminals, and 2) the fact that since Prime didn't have a visual editor, he'd written his own. Because of the magic portability of Pick code, he'd brought his editor down into Revelation, and had built the entire project on the PC using it.
Revelation, of course, being PC-based, had a perfectly good full-screen editor, and didn't object when you went past column 80. However, for the first several months I was there, he insisted that I use his editor and his standards.
So, the first standard was that every line of code had to be commented. Every line. No exceptions. His rationale for that was that even if your comment said exactly what you had just written in the code, having to comment it meant you at least thought about the line twice. Also, as he cheerfully pointed out, he'd added a command to the editor that formatted each line of code so that you could put an end-of-line comment.
Oh, yes. When you commented every line of code, it was with end-of-line comments. In short, the first 64 characters of each line were for code, then there was a semicolon, and then you had 15 characters to describe what your 64 characters did. In short, we were using an assembly language convention to format our Pick/Basic code. This led to things that looked like this:
EVENT.LIST[DATE.INDEX][-1] = _ ;ADD THE MOST RECENT EVENT
EVENTS[LEN(EVENTS)] ;TO THE END OF EVENT LIST
(Actually, after 20 years I have finally forgotten R/Basic's line-continuation syntax, so it may have looked different. But you get the idea.)
Additionally, whenever you had to insert multiline comments, the rule was that you use a flower box:
************************************************************************
** IN CASE YOU NEVER HEARD OF ONE, OR COULDN'T GUESS FROM ITS NAME, **
** THIS IS A FLOWER BOX. **
************************************************************************
Yes, those closing asterisks on each line were required. After all, if you used his editor, it was just a simple editor command to insert a flower box.
Getting him to relent and let me use Revelation's built-in editor was quite a battle. At first he was insistent, simply because those were the rules. When I objected that a) I already knew the Revelation editor b) it was substantially more functional than his editor, c) other Revelation developers would have the same perspective, he retorted that if I didn't train on his editor I wouldn't ever be able to work on the Prime codebase, which, as we both knew, was not going to happen as long as hell remained unfrozen over. Finally he gave in.
But the coding standards were the last to go. The flower-box comments in particular were a stupid waste of time, and he fought me tooth and nail on them, saying that if I'd just use the right editor maintaining them would be perfectly easy. (The whole thing got pretty passive-aggressive.) Finally I quietly gave in, and from then on all of the code I brought to code reviews had his precious flower-box comments.
One day, several months into the job, when I'd pretty much proven myself more than competent (especially in comparison with the remarkable parade of other coders that passed through that office while I worked there), he was looking over my shoulder as I worked, and he noticed I wasn't using flower-box comments. Oh, I said, I wrote a source-code formatter that converts my comments into your style when I print them out. It's easier than maintaining them in the editor. He opened his mouth, thought for a moment, closed it, went away, and we never talked about coding standards again. Both of our jobs got easier after that.
At my first job, all C programs, no matter how simple or complex, had only four functions. You had the main, which called the other three functions in turn. I can't remember their names, but they were something along the lines of begin(), middle(), and end(). begin() opened files and database connections, end() closed them, and middle() did everything else. Needless to say, middle() was a very long function.
And just to make things even better, all variables had to be global.
One of my proudest memories of that job is having been part of the general revolt that led to the destruction of those standards.
An externally-written C coding standard that had the rule 'don't rely on built in operator precedence, always use brackets'
Fair enough, the obvious intent was to ban:
a = 3 + 6 * 2;
in favour of:
a = 3 + (6 * 2);
Thing was, this was enforced by a tool that followed the C syntax rules that '=', '==', '.' and array access are operators. So code like:
a[i].x += b[i].y + d - 7;
had to be written as:
((a[i]).x) += (((b[i]).y + d) - 7);
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 months ago.
Improve this question
I have seen the other questions but I am still not satisfied with the way this subject is covered.
I would like to extract a distiled list of things to check on comments at a code inspection.
I am sure people will say things that will just cancel each other. But hey, maybe we can build a list for each camp. For those who don't comment at all the list will just be very short :)
I have one simple rule about commenting: Your code should tell the story of what you are doing; your comments should tell the story of why you are doing it.
This way, I make sure that whoever inherits my code will be able to understand the intent behind the code.
I comment public or protected functions with meta-comments, and usually hit the private functions if I remember.
I comment why any sufficiently complex code block exists (judgment call). The why is the important part.
I comment if I write code that I think is not optimal but I leave it in because I cannot figure out a smarter way or I know I will be refactoring later.
I comment to remind myself or others of missing functionality or upcoming requirements code not present in the code (TODO, etc).
I comment to explain complex business rules related to a class or chunk of code. I have been known to write several paragraphs to make sure the next guy/gal knows why I wrote a hundred line class.
If a comment is out of date (does not match the code), delete it or update it. Never leave an inaccurate comment in place.
Documentation is like sex; when it's
good, it's very, very good, and when
it's bad, it's better than nothing
Write readable code that is self-explanatory as much as possible. Add comments whenever you have to write code that is too complex to understand at a glance. Also add comments to describe the business purpose behind code that you write, to make it easier to maintain/refactor it in the future.
The comments you write can be revealing about the quality of your code. Countless times I've removed comments in my code to replace them with better, clearer code. For this I follow a couple of anti-commenting rules:
If your comment merely explains a line of code, you should either let that line of code speak for itself or split it up into simpler components.
If your comment explains a block of code within a function, you should probably be explaining a new function instead.
Those are really the same rule repeated for two different contexts.
The other, more normal rules I follow are:
When using a dynamically-typed language, document the expectations that important functions make about their arguments, as well as the expectations callers can make about the return values. Important functions are those that will ever have non-local callers.
When your logic is dictated by the behavior of another component, it's good to document what your understanding and expectations of that component are.
When implementing an RFC or other protocol specification, comment state machines / event handlers / etc with the section of the spec they correspond to. Make sure to list the version or date of the spec, in case it is revised later.
I usually comment a method before I write it. I'll write a line or two of comments for each step I need to take within the function, and then I write the code between the comments. When I'm done, the code is already commented.
The great part about that is that it's commented before I write the code, so there are not unreasonable assumptions about previous knowledge in the comments; I, myself, knew nothing about my code when I wrote them. This means that they tend to be easy to understand, as they should be.
There are no hard rules - hard rules lead to dogma and people generally follow dogma when they're not smart enough to think for themselves.
The guidelines I follow:
1/ Comments tell what is being done, code tells how it's being done - don't duplicate your effort.
2/ Comments should refer to blocks of code, not each line. That includes comments that explain whole files, whole functions or just a complicated snippet of code.
3/ If I think I'd come back in a year and not understand the code/comment combination then my comments aren't good enough yet.
A great rule for comments: if you're reading through code trying to figure something out, and a comment somewhere would have given you the answer, put it there when you know the answer.
Only spend that time investigating once.
Eventually you will know as you write the places that you need to leave guidance, and the places that are sufficiently obvious to stand alone. Until then, you'll spend time trawling through your code trying to figure out why you did something :)
I document every class, every function, every variable within a class. Simple DocBlocks are the way forward.
I'll generally write these docblocks more for automated API documentation than anything else...
For example, the first section of one of my PHP classes
/**
* Class to clean variables
*
* #package Majyk
* #author Martin Meredith <martin#sourceguru.net>
* #licence GPL (v2 or later)
* #copyright Copyright (c) 2008 Martin Meredith <martin#sourceguru.net>
* #version 0.1
*/
class Majyk_Filter
{
/**
* Class Constants for Cleaning Types
*/
const Integer = 1;
const PositiveInteger = 2;
const String = 3;
const NoHTML = 4;
const DBEscapeString = 5;
const NotNegativeInteger = 6;
/**
* Do the cleaning
*
* #param integer Type of Cleaning (as defined by constants)
* #param mixed Value to be cleaned
*
* #return mixed Cleaned Variable
*
*/
But then, I'll also sometimes document significant code (from my init.php
// Register the Auto-Loader
spl_autoload_register("majyk_autoload");
// Add an Exception Handler.
set_exception_handler(array('Majyk_ExceptionHandler', 'handle_exception'));
// Turn Errors into Exceptions
set_error_handler(array('Majyk_ExceptionHandler', 'error_to_exception'), E_ALL);
// Add the generic Auto-Loader to the auto-loader stack
spl_autoload_register("spl_autoload");
And, if it's not self explanatory why something does something in a certain way, I'll comment that
The only guaranteed place I leave comments: TODO sections. The best place to keep track of things that need reworking is right there in the code.
I create a comment block at the beginning of my code, listing the purpose of the program, the date it was created, any license/copyright info (like GPL), and the version history.
I often comment my imports if it's not obvious why they are being imported, especially if the overall program doesn't appear to need the imports.
I add a docstring to each class, method, or function, describing what the purpose of that block is and any additional information I think is necessary.
I usually have a demarcation line for sections that are related, e.g. widget creation, variables, etc. Since I use SPE for my programming environment, it automatically highlights these sections, making navigation easier.
I add TODO comments as reminders while I'm coding. It's a good way to remind myself to refactor the code once it's verified to work correctly.
Finally, I comment individual lines that may need some clarification or otherwise need some metadata for myself in the future or other programmers.
Personally, I hate looking at code and trying to figure out what it's supposed to do. If someone could just write a simple sentence to explain it, life is easier. Self-documenting code is a misnomer, in my book.
I focus on the why. Because the what is often easy readable.
TODO's are also great, they save a lot of time.
And i document interfaces (for example file formats).
A really important thing to check for when you are checking header documentation (or whatever you call the block preceding the method declaration) is that directives and caveats are easy to spot.
Directives are any "do" or "don't do" instructions that affect the client: don't call from the UI thread, don't use in performance critical code, call X before Y, release return value after use, etc.
Caveats are anything that could be a nasty surprise: remaining action items, known assumptions and limitations, etc.
When you focus on a method that you are writing and inspecting, you'll see everything. When a programmer is using your method and thirty others in an hour, you can't count on a thorough read. I can send you research data on that if you're interested.
Pre-ambles only; state a class's Single Responsibility, any notes or comments, and change log. As for methods, if any method needs substantial commenting, it is time to refactor.
When you're writing comments, stop, reflect and ask yourself if you can change the code so that the comments aren't needed. Could you change some variable, class or method names to make things clearer? Would some asserts or other error checks codify your intentions or expectations? Could you split some long sections of code into clearly named methods or functions? Comments are often a reflection of our inability to write (a-hem, code) clearly. It's not always easy to write clearly with computer languages but take some time to try... because code never lies.
P.S. The fact that you use quotes around "hard rules" is telling. Rules that aren't enforced aren't "hard rules" and the only rules that are enforced are in code.
I add 1 comment to a block of code that summarizes what I am doing. This helps people who are looking for specific functionality or section of code.
I comment any complex algorithm, or process, that can't be figured out at first glance.
I sign my code.
In my opinion, TODO/TBD/FIXME etc. are ok to have in code which is currently being worked on, but when you see code which hasn't been touched in 5 years and is full of them, you realize that it's a pretty lousy way of making sure that things get fixed. In short, TODO notes in comments tend to stay there. Better to use a bugtracker if you have things which need to be fixed at some point.
Hudson (CI server) has a great plugin which scans for TODOs and notes how many there are in your code. You can even set thresholds causing the build to be classified as unstable if there are too many of them.
My favorite rule-of-thumb regarding comments is: if the code and the comments disagree, then both are likely incorrect
We wrote an article on comments (actually, I've done several) here:
http://agileinaflash.blogspot.com/2009/04/rules-for-commenting.html
It's really simple: Comments are written to tell you what the code cannot.
This results in a simple process:
- Write any comment you want at first.
- Improve the code so that the comment becomes redundant
- Delete the now-redundant comment.
- Only commit code that has no redundant comments
I'm writing a Medium article in which I will present this rule: when you commit changes to a repository, each comment must be one of these three types:
A license header at the top
A documentation comment (e.g., Javadoc), or
A TODO comment.
The last type should not be permanent. Either the thing gets done and the TODO comment is deleted, or we decide the task is not necessary and the TODO comment gets deleted.