If it’s important enough to comment, it’s important enough to test
Several people disagreed when I said you should try to write code that doesn’t need comments. I’ll be addressing some of their thoughts — sometimes by saying they were right, but sometimes with constructive suggestions.
I’ll start with a couple of people who suggested that comments should try to explain code that was put in to fix a bug, or to explain the “tricky code” that you sometimes have to write.
Those are both scenarios where a comment isn’t enough. You need an automated test.
Tricky code
The best way to deal with tricky code is by not writing it. But I’ll assume you’re dealing with a case where some manner of tricky code is indeed the best way to get the job done.
Suppose you’re writing a Delphi constructor, and for some reason you need to put some code before the call to inherited Create. (That certainly qualifies as tricky.) Assuming there’s a reason why that’s necessary (and not just sloppiness), you should have an automated test that proves the resulting behavior is correct… something that will pass with the tricky code, and will fail without it. A test that would break if someone else (or you, for that matter) later misunderstood the importance of that ordering, and “fixed” it by moving the code after inherited Create. A test that would pass if someone found a less tricky way to accomplish the same thing.
Bug fixes
If you’re fixing a bug, you should definitely be writing an automated test, if at all possible. That way, if someone later makes a change that breaks the same thing again, you’ll know. As Brian Marick said (and we had posted on our wall for a while), “No bug should be hard to find the second time.”
Then look again
Once you’ve got your automated test, take another look. Is the comment still necessary?
Depending on your audience, maybe it is. As someone else pointed out, if you’re a library vendor, then comments have a lot of value.
But I often find that, with the test in place, the comment can just go away.
February 14th, 2008 at 1:34 am
Let me give some examples of important comments:
- Automated comments that ensure, that if an investor asks you “Do you have documentation for the source code?” You can definitely answer yes without spending a lot of time on writing it.
- A standard is violated in some code. You don’t understand this violation and would like to bring the code back to the standard, but then you read the comment that explains, why this code is not conforming. I can mentioned one of many of such in our code: “Because of a compiler bug, this may fail rarely at some customers if it is not written this way”
- The purpose. You can see what the function does, but now the environment changes, so the function needs to be changed. But depending on the purpose of the function, you can change the function in several ways - so you need to know the purpose of the function before you can modify it correctly. Since the purpose is not always representable in identifiers, comments may be needed.
- Comments for the translator. You have the string ‘%s, %s %s’ and the translator needs to translate this. How does the russian translation look like, for ‘%s, %s %s’ ? A comment, which is written by the programmer and read by the translator may help the translation process a lot (http://dxgettext.sf.net/).
Anyway, your wrote your articles after reading my article. It somehow seems that you missed the point of my article. My article basically says:
- A lot of people require comments to be present.
- My article describes a lot of things not to comment, and how to reduce the number of comments.
Anyway, one of the most important design criterias for source code readability is this one:
- What do others think?
This is important, because the programmer’s own opinion isn’t really important - he already knows the code. That’s why we have source code review in our teams, and if other people than the original programmer consider the source code difficult to understand after a few seconds, a lack of readability issue is made in the issue tracker system.
February 14th, 2008 at 7:37 am
1. The best comment is understandable code. If code is written in a very clear way, in most case, a comment is not necessary.
2. The detail level of comments is depend on the reader groups. If readers are students (esp. without any programming experience), then comments should be more detailed. If readers are experienced programmers, then comments can be very brief.
3. I potential agree with writing test case for tricky code. But I strongly recommend to put comment in code (background, issue id, solution, etc.) as well. When you or your co-workers review your code later, you can get a quick image of the problem. Test cases are always welcome, but if developers do not run these test cases (forgot or it is responsibility of QA), your tricky code might be broken by their changes. And then you will investigate more time on fix this problem. (This happens very often by merging changes)
My point is that, do not put your BIO in comments. But write necessary thoughts, explanations as comments. They will be not compiled, so it is absolutely harmless.
stanleyxu
February 14th, 2008 at 9:00 am
i agree completely. i have been a great proponent of commenting but as my experience has grown, i’ve come to realize that when i find myself thinking “i should comment this”, it usually is a sign of one of the following:
- poor naming
- the routine must be broken into smaller pieces
- the routine has some side effect that isn’t good style
- there’s something tricky being done here (is this really necessary to be tricky)
so now that i realize this, 3/4 of the time i end up making the comment entirely unnecessary through improvements on this. as you say, comments get out of date and can become misleading.
if the code makes the comment unnecessary, even better! it’s not that i’m reluctant to make comments (i’m not) but if the i can make them unnecessary, i prefer that instead.
occasionally there’s a situation where it’s important to say why a certain thing is done first or to describe an intent and these _must_ be commented.
February 14th, 2008 at 12:30 pm
Lars,
You make some great points. I never said you shouldn’t comment; I’m just trying to challenge the people who have never thought about doing anything else. Some of the things you bring up are good candidates for comments.
However, I think you missed the point of this post, because you didn’t say a word about tests — and one of the items you mention (working around compiler bugs) is just begging for automated tests. If you can write an automated test that proves the codegen is wrong, then you’ll know you can’t undo that tricky workaround code — or will find out pretty quick, if you try. It also gives you a repro case to attach to your compiler bug report, and makes it much easier to find out whether the next version of the compiler really fixed the problem or not.
As I said in this post, once you’ve got that test in place, then whether you keep the comment is up to you. That’ll depend on who else will be working in that code, how good your continuous build is, and your own personal preference.
February 14th, 2008 at 2:04 pm
One of the problems with tests verses comments is that for some reason, the test suite is not maintained or passed on to the next ‘contractor’. This is when comments appear to be a winning solution. Back in the ‘good old days’, David Thielen wrote a book on self tests No Bugs!: Delivering Error-Free Code in C and C++ This book suggests that in each source file should contain a self test routine that could be called during program execution… thus every time a programmer/tester ran the application, code tests would be run. It seems to me that in a shop where the luxury of test harnesses are not integrated in the development process, this technique may be a viable option.