What is Well-Commented Code? 826
WannaBeGeekGirl queries: "What exactly is well-commented code anyway? Can anyone suggest resources with insight into writing better comments and making code more readable? After about six years in the software development industry I've seen my share of other people's code. I seem to spend a lot of time wishing the code had better (sometimes _any_) comments. The comments can be frustrating to me for different reasons: too vague, too specific, incoherent, pointing out the obvious while leaving the non-obvious to my imagination, or just plain incorrect. Poorly or mysteriously named variables and methods can be just as confusing. In a perfect world everyone would follow some sort of coding standards, and hopefully those standards would enforce useful comments. Until then, any suggestions for what you, as a programmer, consider to be good/useful/practical comments? Any suggestions for what to avoid? Also, I usually work with C++ so any resources/comments specific to that language would be too."
Code Complete (Score:5, Informative)
Re:Code Complete (Score:5, Insightful)
Yes, that's on my bookshelf -- but, given the fact that they go to great lengths to point out the importance of checking for buffer over/under-runs and fencepost errors, one can't help wondering if (in the wake of all those critical bugs in IE/Outlook/IIS) any of Microsoft's own programmers have read it.
More "do as we say, not as we do" from Microsoft?
Re:Code Complete (Score:2)
Re:Code Complete (Score:3, Funny)
*Abruptly stops the finger from clicking the link*
like a book on nutrition (Score:3, Insightful)
By all means, read Code Complete--its suggestions are sensible. But the real culprit when it comes to poor software are time and resource pressures, feature creep, and other environmental factors. Maybe at least the book will let you recognize when your project is doomed and leave; McConnell seems to have done that--he isn't at Microsoft anymore.
Re:Code Complete (Score:2, Insightful)
e.g.
// check to see if whatever is true
if ( [complex bit of code] ) {
do something;
}
This is much better written like this, without the comment:
Whatever = [complex bit of code];
if ( Whatever ) {
do something;
}
He gives lots of examples like this, showing how to write your code so it doesn't need so many comments.
Great book.
Make the variable names mean something! (Score:2)
Re:Make the variable names mean something! (Score:5, Informative)
I strongly disagree. The proper delineation of a function or method is the operation that it abstracts, not how long it is.
If a subroutine is only called once, and doesn't cleanly abstract some idea (i.e., if you can't tell me what it does in one simple sentance), it should not be in a separate subroutine.
I've seen too much code written in the manner you suggest, that makes the reader bounce around from function to function to function for no reason other than "otherwise that function would be more than 30 lines".
If I have to maintain such code I always refactor it into one subroutine.
Describe before you apply (Score:3, Funny)
ie,
while (1) {
}
Re:Describe before you apply (Score:2, Interesting)
while (1) {...}
or more commonly
for (;;) {...}
is a well known construct for infinite loop. If you turn such a simple construct into six lines of source, then I dread to think how much commenting you'll use when you actually get down to solving the problem in hand.
for (;;) { // infinite loop
is far better - it reminds people what you're doing and if someone sees your code and doesn't understand that construct then they know what it does from the comment and they can go and find out how it works and learn it for next time.
While you're at it, you should probably think about hiring real programmers who know basic constructs in their chosen language...
Re:Describe before you apply (Score:3, Interesting)
1) It reads right in english.
2) It's type-safe in C++ for -Wall.
3) It doesn't use antequated or obfuscated C-isms.
I can't stand things like: ;;
...
#define ever
for (ever) {
Multiple passes to your code (Score:4, Insightful)
One day you're commenting on what variables do, the next you try to explain functions, etc.
I just switched to Java from C++ and neatness is the most important thing I've acquired, not in code per se, but in variable naming. I've gotten used to doingThisWithVariableNames and DoingThisWithClassNames, while keeping THE_CONSTANTS capitalized. Ok, this isn't comments? But you'll be surprised at how much better it is to browse a new language like Java and see the norms of style in it, because old languages use too many confusing double_StandardslikeWritingThis_way.
Comments go at the top of a page, with the coder's name and date, as well as a small bug report and if you can, a brief function list for those without a visual IDE like JBuilder. You then put a like with PRE: and POST conditions in your code and try to keep one liner comments to a min.
I learned to comment the end of if structures and function blocks to make the code easier to follow... just add " }
Comments should be a paragraph long so that they make some sense. And comments, since they look different from the code sections, should be embelished with ===============, stars, and some
nice spacing and vertical bars.
Good comments to me mean good-looking comments, even if they don't have that much substance. Just my 2 cents. They're better than no comments at all.
Microsoft Press (Score:2)
Writing Solid Code by Steve Maguire
Per project (Score:2, Insightful)
A good standard for C++:
http://www.possibility.com/Cpp/CppCodingStandard.
Timeless Prof D.Knuth says it best... (Score:2, Informative)
Re:Timeless Prof D.Knuth says it best... (Score:2, Informative)
"CWEB is a version of WEB for documenting C, C++, and Java programs.
The CWEB page [stanford.edu] also includes example programs, but you will have to run them through CWEB to get the hyperlinked PDF files.
Re:Timeless Prof D.Knuth says it best... (Score:3, Insightful)
Programmers have the weakness of thinking that they are writing for a compiler. They should be imagining that they are writing for another human reader. This is the essence of literate programming, which is, in my opinion, the only good idea that anyone has ever had about program documentation.
If the programmer is restricted to interspersing comment lines between lines of code, then the elaboration of the documentation must follow the sequence of the code. To use a simple example, if I write a class definition, then I must declare all the member variables within the block of text that begins "class foo" and ends with "};". However, that may not be the best way to explain the significance of those variables. Maybe it would make more sense (for the human reader) to delay the declaration of a member variable until the place where it is first used. This can easily be done with CWeb. This simple example is hardly sufficient to reveal the power of LP. It is well worth taking a serious look.
After the literate program is written, it is processed by two other programs. One produces a file suitable for submission to a compiler. The other produces a TeX file, which outputs a properly formatter version to be read by a human.
The code itself is never the best documentation. It's not documentation at all, except in the most trivial cases.
Any programmer can write a literate program. It's just a matter of understanding who his audience is.
Just tell me what a section of code is for. (Score:2)
I've never had to deal with 'obfuscated' code so I don't know about onscure variables, etc.. or how much more complicating they could be to my task.
Just point me in the right direction. Anything else is going to be too much or too little... and if I don't already know what the code is supposed to be doing I probably should be talking to someone who does before I sit down to work on the code itself.
Obviously reverse engineering of software is a whole different beast.
Re:Just tell me what a section of code is for. (Score:2, Funny)
I thought Perl was the most efficient self-obfusicating code ever.
Good Comments (Score:4, Insightful)
I then write inline comments in the code describing it's flow. It's only then do I actually write the code.
Comments at file/class level should describe what it does and is used for. It should also describe how it fits in with the big picture of it's packages and the classes around it - give a reader some architectual scope to what they're looking at.
Get into a habit, even for trivial functions/methods and you'll soon not realized you're doing it.
Some people say code shouldn't need commenting, and the code itself should be enough. In a perfect world of no bugs and only populated by wizard programmers, this is fine, but not in the world I live in. You write some code and someone else (maybe yourself) will have to debug it at some point - maybe 3-4 years down the line. Even with a "neat" language like Java, working out how things work is much more time consuming without comments.
Re:Good Comments (Score:4, Insightful)
Congrats, you've just described a maintenance nightmare.
Every time someone has to change some code, you've just forced them to double their workload, and change some comments too.
If they forget, or don't have time, or are lazy, or don't notice the comment (it's easy to blank them out) then the comment doesn't get updated.
Now you have a comment that is wrong. And that is so so so much worse than having no comment at all.
Comment sparsely. Do not sprinkle your code with comments. Especially do not use comments like
// increment loop counter
loopCounter++;
That is adding zero value.
Inline comments are a major headache - they're painful to write, painful to maintain, and dangerous if they aren't maintained.
~Cederic
Re:Good Comments (Score:5, Insightful)
I'll repeat that: they MUST change the comment. And it must make complete sense when they're done or they'll be out of a job!
Why is this important? When you change the comment, you must think about the comment. You must think about the change you've done and how it fits in with the rest of the code, and what the rest of the code is trying to do. If a comment isn't up to date or doesn't make sense, that's a bug in the code, as bad as any other, and it needs to be fixed.
It's not difficult to spot when the comments don't line up, so they're fairly easy to fix. While you're there fixing the comments you need to check the code, 'cos whoever the idiot was that wrote it, they obviously haven't checked it properly. Go and hit them with a Very Big Stick.
Certainly you shouldn't whine about the extra typing. A little extra typing shouldn't hurt - and you should be able to type faster than you can think, so it shouldn't really slow you down. If it does, go take a typing class.
And if your lame excuse is that you're in too much of a hurry to maintain comments, just make sure you're not in too much of a hurry to deal with the bug reports that come back because you haven't checked your code properly.
They MUST vs. they WON'T (Score:3, Insightful)
So, it's one thing to say "if they change the code, they MUST change the comments", but realize that unless you have the ability to force the issue (a tool to make you change comments before saving changes, managers who care more about firing programmers who don't follow code standards than avoiding schedule slippage -- hint: I've never seen one of these, EVER), 9 times out of 10, they just won't do it. It's like teaching abstinance as a method of reducing teen pregnancy.
Thus, the practice of having comments which are redundant w/ the code is simply setting the project up for failure as the parent poster pointed out.
Re:Good Comments (Score:4, Insightful)
... and absolutely essential to the poor bastard who comes after you - without them he has zero chance. I spent some hours on the phone a couple of days ago talking some poor lad in the states through the trickier bits of one of my open source packages. Fortunately it is inline-commented, so I at least knew what I had been intending to do.
I agree with everything you say about the nuisance of maintaining comments, and I agree with everything you say about the problems that happen when you fail adequately to maintain comments. It's a chore; but it's a vital chore. It's got to be done.
It's sophomores like you... (Score:5, Informative)
Comment sparsely. Do not sprinkle your code with comments. Especially do not use comments like
Yea, I can already picture your programming style. You'd make a 200-line function with the only comment being "
loopCounter++;
That is adding zero value.
Yes, because it's one line of code, and the code is described through the variable. But when sifting through lines of code, you often find beautiful works like iHateMyJob++; or fuckMyBoss--; to name a few. And needless to say, they're uncommented in the code. Until computer code can be written bug free in complete English sentences (aka Never), the rest of your team of workers needs to understand what your code does.
Personally, I make sure every function says what goes into it, what comes out of it, and what setup (variables, etc.) need to be made for it to be called. I do not comment every single line of code, but I do make sure that every line is accounted for by descriptive sentences, explaining the task that I wish to accomplish as well as what variables / registers / actions I take to accomplish the task.
Every time someone has to change some code, you've just forced them to double their workload, and change some comments too.
Okay, this just pisses me off. You didn't mean what you said. Here's what you meant to say:
Every time I have to change some code, you've just forced me to double my workload, and change some comments too.
I can assure you, from a reviewer's point of view, comments SAVE my time from trying to understand what each piece of code is trying to accomplish. Commented code may make you work extra time to detail the lines of code (I do admit, some programmers are quite tallented at keeping track of every single line of code in their head as they work on it on the computer), but it saves tremendous amounts of time once that chunk of code needs to be integrated with other chunks of code into the final product.
Re:Good Comments (Score:3, Interesting)
However, I completely disagree with your premise about this being a maintenance nightmare and doubling workload.
It's the exact opposite of a maintenance nightmare - it helps maintenance (certainly for long running large projects with developer turnover).
It's also very little overhead. If you are a professional developer, just count how many hours you really write code in a week of working. It's not a great deal really, and the added time to add good comments is very little. The rewards of doing it are far greater than any costs.
This is a complete mindset thing, just like coding standards - if you get in the mindset, it's easy and no cost, if you moan and complain and fight them all the time it's a pain and loads of work.
Re:Good Comments (Score:3, Insightful)
The comments should talk about _what_ the module dues, not _how_ it does it. Stick with this distinction and it'll be a bit easier. If your module changes so much that the _what_ changes... then you really should take the time to reconsider your comments... as they may point out what assumptions other code may be making and where compensating changes may be needed.
Better practice-- inline comments tell why not how (Score:3, Insightful)
Inline comments have a place, but they are way over used. If you are telling me how your program works using inline comments, I will ignore those comments becuase if there is a problem, your code may not behave as advertized.
Instead inline comments should document WHY you do something a certain way and help me to understand what problems caused a particular piece of code to us a particularly clumsy algorythm or why a seeminly extranious bit of code was added. Don't tell me how-- that is what the code is for.
And use whitespace as your friend to break things up into logical chunks which are easily readable and logically connected. This is the reason for indenting your code, but the same principle can be used by adding additional line breaks to separate logical chunks of code (this makes more sense then meaninglessly breaking up functions).
I think that these are relatively language independent advice. I use it in Perl and PHP, and when I read C and C++, I appreciate these tips as well.
my work (Score:2)
about 1/4 of my lines are comments -- most all of which are incorporated into doxygen descriptions -- and the rest only appear in the sourse listings
see http://www.doxygen.org/
Re:my work (Score:2)
JavaDoc or Doxygen. I've used both and used to love
Doxygen, it's superbly flexible and easy to use.
It helps to gather up the real things people should be commenting; pre-conditions, post-conditions etc
and not "Infinite loop".
Plus it looks nice presenting your docs on a
website as part of the nightly build, or printed
out as a (huge) pdf book. All for no hassle.
Use plenty of expletives (Score:5, Funny)
// no fucking idea how this works
obj.doMagic();
or...
//bet those fucking lazy cunts in the QA team don't pick this up
fileSystem.delete();
When your code is released as open source and becomes famous, people can amuse themselves by searching through the source code to find all the hidden expletives, sort of like easter eggs. If you work for a commercial organisation, you can sit back and enjoy the panic as the QA and release teams sweat it out trying to track down every last filthy utterance before shipping to a fucker...errr..customer.
Re:Use plenty of expletives (Score:2)
Re:Use plenty of expletives (Score:3, Funny)
Re:Use plenty of expletives (Score:2)
I counted 26 legitimate guns n' roses references in the linux-2.4.2 source.
Re:Use plenty of expletives (Score:4, Funny)
Funny variable names are sometimes related to say specific bugfixes a certain individual or customer has demanded.
I know one person where very large customer demanded a specific and very idiotic new feature to the software, due to the customer being an idiot.
Executable was not stripped.
The variable name to control this feature in certain functions was thus called IsAFuckingIdiot
Customer by convention always ran nm on all new executables they installed.
Customer got very upset.
Doxygen, etc (Score:5, Informative)
Doc & code sync always drifts! (Score:3, Insightful)
It's less of an issue w/ Javadoc and Doxygen comments (which is embedded in the code) than external documentation, but the fact is that managers reward code changes, not documentation changes, and programmers are lazy.
Until you can change these basic, simple facts, what are you going to do? One strategy is to encourage self-documenting coding standards as well as encourage documentation updates. But people NEED to remain aware of the basic principle that the only authoritative documentation is the source code itself.
Different parts of the brain (Score:2, Informative)
Quality of comments varies.
I've seen code from the 'hardcore hacker', who believes that the statements themselves suffice as comments - 'the code is intuitively obvious, and it comments itself'.
I've also seen code from complete lamers, who dilute the code terribly with irrelevant shit:
i++;
Over the years, I've noticed that composition of code, and commenting/documentation of code, tend to draw on two different parts of the brain.
Often, I find myself in a 'zone', where the code flows freely, and where commenting code feels like a total distraction.
Other times - for instance, when I'm hunting an elusive bug, I find a different part of the brain kicking in - and at that stage, I find it easier, even pleasurable, to add meaningful comments, to change indenting, variable names etc, as if I'm narrating the code to someone else.
I guess it's a matter of balance, and using the right mental faculties at the right time.
A good rule of thumb is to imagine that someone else is sitting beside you, someone less acquainted with the task than yourself (eg a non-technical manager). Imagine you're explaining to him/her how the code works, and put these explanations in the code as succinct yet clear comments. Imagine this person asking you, 'what's that variable'. Don't be afraid of global search'n'replace of identifier names across all the applicable files. And imagine this person sometimes getting up and leaving you in peace, so you can have those precious moments to hack to your heart's content.
In conclusion, I feel that much of a person's personality can be read from one's code. Is someone fundamentally easygoing and helpful, and caring about others? Or is someone a complete egotist, emotionally shut down almost to the point of autism? In my mind, the ability of code to communicate its intent and methods to other programmers is almost as important as the code successfully performing its task, since its communicability directly affects the ability and interest of others in working on it, and thus its openness to manpower leverage.
It's been a long time but.. (Score:5, Interesting)
First-up you need a good spec -- and the spec should include the user-interface details to the extent that you could actually write the user-manual from that spec.
Indeed -- if you can't write the user-manual from the spec then the spec is incomplete.
From the spec the programmer should develop the structure of the code in another document.
That structure document is repeatedly refined in a top-down process until you (eventually) reach a point where you're actually cutting code.
I was always surprised just how much easier it was when the code was written as the lowest level of the structure documentation.
Not only could you comment out the program structure document so that the compiler would ignore it -- but you ended up with absolutely accurate and comprehensive documentation built into that source.
Project managers love this technique (and when I was in a project management role I demanded it of my team) -- it ensures that technical and end-user documentation are no longer the bits that get left until last and thus are either very shoddily thrown together or, if the project goes really over-budget, not produced at all.
Of course, as we all know, there's a huge amount of temptation to just leap into coding at the earliest possible stage and leave the documentation until later -- because some stupid managers use number of code-lines completed as a metric of project performance -- duh!
If you're smart and use good tools you can selectively collapse and expand the in-source documentation so that when you're trying to get familiar with a module that someone else has written, you can descend down the structure tree one level at a time without the meaning being diluted by stuff that is at a lower level.
Unlike the days of interpreted BASIC, there's very little overhead involved in integrating documentation and code these days -- so there's no excuse not to do it.
If required, the documentation can be automatically extracted from the source -- but by keeping the master copy in the code it becomes easier to ensure synchronization as changes and updates are made during the lifecycle of the project.
Re:It's been a long time but.. (Score:3, Interesting)
Alas, since the UI is wholly divorced from the back-end (I discovered I'd designed in my head an n-tier system just by seeing what I hated about both similar and unrelated software I've been forced to work with), I'm not sure I could follow everything precisely the way you suggest. After all, in the overall design, there will actually be several clients, each displaying data appropriate to its interface (web vs. fat client vs. text vs. scripted API vs. ???). I know what I can, and in fact must, do is define just how the "back end" (in terms of the clients) tells the clients what to display, what to get from the user, etc.
I've also got to point out that in the past, I've been guilty of the "jump right in and code immediately" method of development. Unfortunately, I didn't have much in the way of control, since we were under pressure from both upper management and the customer (they have a lot of boats and guns...) to produce code for testing immediately.
Even though this was for a "next generation" of a system already in place, it was a complete rewrite in a language the customer wasn't all that familiar with (C++), and so they were concerned that we wouldn't be able to guarantee anything would even work, let alone within the tight timing constraints required by parts of the overall system that weren't being changed.
We had to deal with collecting all sorts of assinine metrics, such as the SLOC (Source Lines of Code) you've mentioned. Of course, the number of comments was also a metric that needed to be collected, and so we somehow had to find time to do those while frantically trying to keep pace with specs that seemed to change arbitrarily on a weekly or monthly schedule. Assinine? Yes. Real life? Yes. The only saving graces were that we'd managed to convince everyone who made decisions that some ridiculously low SLOC count was what we were responsible for in terms of monthly performance (giving us some breathing room to do intelligent design), and regular (weekly) code reviews amongst all the developers, spec writers, and the customer, to verify that what we were doing was, in fact, correct. (Though it seemed at times that we spent the majority of the meetings teaching all of the non-developers how to code in C++)
Re:It's been a long time but.. (Score:3, Insightful)
Yes, we can tell it's been quite a while.
Right now, businesses go to their IT teams and say "We need software that does X. Deliver it in 8 weeks."
It would take 8 weeks to write a structure document in the manner you are describing (especially going through the various top-down iterations to reach code).
Instead we have to write the basic framework of the solution, get that ready in four weeks, and then change and tweak all the little pieces of functionality that have changed in the requirements since we started. Because businesses don't know what they want, and all that is definite is the go live date (usually because the Marketing team have a fixed launch date)
How are you meant to pre-document a requirement that arrives three days before go-live? With a suitable methodology you can add it, test it, and regression test the rest of the system to be sure you haven't broken it. But then generating user documentation too? Dream on, that's going to have to wait.
~Cederic
Re:It's been a long time but.. (Score:3, Interesting)
In web development, your dev cycle is often 3 months or fewer, with support cycles measured in days or even hours. The practice of shifting requirements up until the ship date is one that we, as professionals, have a duty to curb. If you're implementing new requirements during the final 10% of the project, then you're allowing the customer to break the project and blame you.
Unfortunately, the nature of programming doesn't really change between those extremes: it's still a question of figuring out what the problem (the product requirements) is, designing a solution to the problem (writing a spec and, hopefully, designing it so that three cycles from now when you get a requirement to change the product, you can), and then writing the code that implements the design.
The comments we always see in these discussions along the lines of, "comments are for the weak; real programmers don't use comments..." don't take into consideration the fact that the odds are very good that you won't be supporting your own code in a year, you'll be dealing with someone else's crap. As professionals, it behooves us to provide as many clues as we can to the poor sods who'll follow after us -- because what goes around, comes around.
When I'm doing really fast web development, the spec is often a drawing on a white board -- so I take a picture. The design is often a doodle in a notebook -- which I label and keep on my bookshelf. And when I start banging out code, the first thing I do is pseudocode in comments, then interleave the real thing. That way, when I'm interrupted in the process, I can pick up again quite easily.
I've handed off a lot of code to other people, and I've never gotten any complaints about too many comments (or about useless ones). I have gotten comments about how easy it is to follow what I'm doing, and that's enough. Do what you need to do to get the job done, but keep in mind that the job doesn't stop with getting the thing to compile and link.
Re:It's been a long time but.. (Score:3, Interesting)
That style of programming leads to unreadable and unmaintainable code. The problem is that, in many cases, the programmer that required reams of documentation in order to write the code also requires that documentation in order to read it. The system-level become inappropriate to the evironment and language being used since the design was done "in your head" instead of "in the code.
IMHO, detailed specs should only be done when there can be a GAURANTEE that it won't change for at least 2 years. The is is the usually the case with specs produced by groups like W3C, IETF, or the OMG, and a lot of programmers think they should copy the activities of these beauricratic organizations in their own work, where requirements can be expected to change continuously. In this environment, maintaining a detailed specification that is separate from the code is far too impractical. It's better that programmers make the code and the focus of their attention and make sure their code *deserves* to be the focus of attention (i.e. it's well written, elegant, easy on the eyes and mind, fun to take walks on the beach with, etc...).
-n00m
Re:It's been a long time but.. (Score:3, Informative)
What you are describing (and quite well) is the top-down programming practice. There's a big problem with it, though: in the real world, things change. As others have pointed out, you can't be guarenteed to be able to hammer down a specification that will be satisfactory for a year, or a month, sometimes even a week or a day. Some customer, some manager, or whoever, will demand a change in the final product. What will you do then? You will have to change your entire structure around and that can be extremely difficult.
Fortunately there are other ways of approaching the problem. One of them is called the bottom-up approach. The basic idea is to create a mini-language that one can better formulate your problem in, and then start putting the pieces together. This is complimented by dynamic semantics that languages such as Common Lisp or Smalltalk have. Incremental, interactive compilation and development is well supported by these environments. The code winds up being self-documenting because you wrote it in a mini-language! Weirdly obfuscated--but necessary--as well as commonly used pieces of code can be abstracted with Lisp macros. Changing your data-structures is no problem, already in-use data-structures can be dynamically updated (and you can control how it happens). Errors are handled by the exceptional condition system (no pun intended) and the program can be continued from where you left off, after being fixed. Always you have a working, running codebase.
Document the function's contract (Score:5, Interesting)
Take a look at this function, and tell me if there's a bug:
Easy, the bug's the SEGV, right? Take a look at the same function, this time with comments:
The point? A bug is unwanted behaviorm, but that only makes sense if you've defined what the correct behavior is. My example is trivial, but often this is a real concern. Function "bar(int,int)" returns null whenever one of the arguments is negative--is that a bug or a feature? Your function has a goal in life, a contractual obligation to do something; make sure it's clear what that something is.
Note that if you choose good function and good variable names, a simple one or two line comment at the beginning is usually sufficient to document whe function's intended behavior.
I also find that an "assert()" or two on the arguments at the top of the function makes it clear what values the function accepts, and which one the function doesn't handle. It's an easy way to document the contractual obligations of the function.
Stuff not to put in comments is stuff that's easily devised from the code. Check this out:
Did the "Inputs" or "Outputs" add any value? That information appears again, two lines below in the function definition, and it's guaranteed to be correct there (unlike the comment which will be out-of-date and wrong when we change "square" to work on longs). The "Used by" might have added some value, if it was correct, but as it turns out it's out of date, and 15 other functions now use "square". Any information better derived looking at the code should be left off. Any information which can be better found using "grep" or "find in files" should be left off. Any information that will probably be out of date at some point should be left off. Heck, in this situation even the description is probably extra verbiage, since it doesn't really help anyone. (I'd probably put it in out of habit anyway, though...so sue me:)
Re:type* var is evil (Score:2)
OTOH, char* foo is arguably more logical than char *foo. You are declaring foo as being of type "character pointer". You are not, in fact, declaring a char with a pointer to it named foo (you never declared the char, only the pointer), which is what is implied by your recommended form.
Re:type* var is evil (Score:3, Informative)
*foo means 'foo dereferenced'. In a type declaration, 'int foo' means 'foo is an int', so 'int *foo' means 'foo dereferenced is an int'. And, therefore, foo is a pointer to an int.
So, it's actually quite logical. In this: 'char foo, *bar', we declare that two things have type 'char': foo, and the thing that bar points to.
Re:type* var is evil (Score:2)
Take 'char *c'. This says that *c is a char. So what is the type of c? Working backwards, it must be pointer to char. Or with 'char (*c(int))' you can see that *c(int) has type char, so *c must be a function taking int and returning char, so c is a pointer to such a function. The cdecl tool can help with figuring out the more complex cases
Re:type* var is evil (Score:5, Insightful)
char* foo, bar;
was good coding practice, while
char *foo, bar;
wasn't, because the code was declaring two pointers, and so the * should be with the type and not the variable name.
Even pulling out K&R, and writing sample code showing the sizeof(foo); vs the sizeof(bar); wouldn't convince him that he was wrong.
Unfortunately, I don't think it was ever "officially" settled. Nor were several of the other corrections that I immediately made to his "proposed" coding standards document he handed out at the first meeting.
Thankfully, my manager at the time listened to me (and also, helpfully, knew C and C++), so when we got the coding standards, they were filed with the rest of the useless paperwork we got, and we kept on writing things properly, including:
Three guesses as to which project was ahead of schedule. (Of course, not entirely fair, since we also didn't force code generation via Rational Rose. We instead reverse-engineered all of our final UML from the code we'd written and tested, and knew worked the way it was supposed to...)
Re:type* var is evil (Score:2)
char* foo, bar;
looks like: (char*) ((foo),( bar));
behaves like: (char)((* foo),( bar));
You get the same effect from:
y = x * a+b;
Re:Braces (Score:2)
This means: for C, follow the style in K for C++ get a copy of Stroustrup's book and follow the style he uses; for Perl read the perlstyle(1) manual page; and for Java follow Sun's conventions. This gives you the best chance of interoperating with other people's code.
Of course, if you're doing development within a larger project, such as adding code to an existing program or writing a new utility to add to OpenBSD, then you should follow the local style conventions. Just find what the local 'source of authority' is, and follow that.
Examples.. (Score:5, Funny)
from /usr/src/linux/Documentation/CodingStyle (Score:2, Informative)
Comments are good, but there is also a danger of over-commenting. NEVER try to explain HOW your code works in a comment: it's much better to
write the code so that the _working_ is obvious, and it's a waste of time to explain badly written code.
Generally, you want your comments to tell WHAT your code does, not HOW. Also, try to avoid putting comments inside a function body: if the
function is so complex that you need to separately comment parts of it, you should probably go back to chapter 4 for a while. You can make small comments to note or warn about something particularly clever (or ugly), but try to avoid excess. Instead, put the comments at the head
of the function, telling people what it does, and possibly WHY it does it.
PDL it is good no? (Score:3, Interesting)
Linux and other things. (Score:4, Insightful)
A style suggested in Code Complete (I forget what they call it) is to write a method completely in pseudo code, make sure it's correct, then insert the actual programming code under each line of pseudo code. This technique, while clever I find leads to many useless comments like "loop through the employee records" and "increment the counter".
A good test to see if the comments are working is through a code review, people will very often not know what's going on, or point out confusing comments or code that needs a better explanation. Code Reviews really improves your idea of what good comments are and teaches you what works and what doesn't.
Good commenting (Score:3, Insightful)
1. Every class should have a clearly defined public interface and documentation of:
a) what the class is for and (if appropriate) why it was designed the way it was
b) how it works
c) how to use it
d) how to extend it (if there's any reason to do so)
e) it's lifetime / memory usage(if appropriate)
f) if it's tightly connected to any other classes or functions, that should be documented
g) how to make classes derived from it (if appropriate)
2. Every function should have a comment that says:
a) what it does
b) why (if there's any question)
c) what side effects it has (if any)
d) what side effects it depends on (if any)
e) if the functions is tightly bound to any parts of the program (it's not a context free sort of routine) then you should list where it's called from.
f) examples of how its used (if appropriate)
g) This one is important: describe the algorithm. It's important to keep this sort of comment up to date.
I'm not so enthusiastic about comments on individual lines of code. They seem less necessary to me than the other sorts of comments, especially if everything is well named.
I've been trying to get people at my latest company interested in code documentation, but I seem to have lost that battle. It's a shame. The only way to develop around here is to read every damn line of code, and that's unbelievably wasteful.
Rocky J. Squirrel
Why not what (Score:2)
When comments are useful is to fill in information that is obvious to the author but not obvious to anyone else reading the code. When the author wrote the class/function he knew why he was doing it, why the function was needed at all, this kind of information allows a new developer to get an overall understanding of the project much faster.
code comments (Score:2, Insightful)
If the code is well structured, variables, classes, methods, etc. well-named and well-conceived, it will explain itself to a large degree, and won't require an English play-by-play of every friggin detail. Generally, it's a good idea to have high-level comments that say "this chunk of code does X", but lower-level comments are often a waste of time, and only serve to clutter the code. Having said that, sometimes code is unavoidably hairy, and you have to recognize cases where the code needs some lower-level explanation, and provide it. First, avoid complexity, failing that, manage it. Generally speaking, I think code comments serve the purpose of helping s/w people to develop a mental map of the code. Code should have as few comments as possible, but no fewer :-)
Pseudo code and formatting (Score:2)
Function and variable names that make sense go without saying - they may be a pain to type in, but in the end they don't hamper code efficency, so make them as self-explanatory as possible (with exceptions like using i and j for a 5 line for loop.) Remember, whitespace and good, CONSISTENT formatting is just as important as good commenting. Funky, inconsistent formatting pisses me off just as badly as cryptic commenting and 6-character all-capital variable and function names.
I comment under the assumption that the next time I look at this code, it will be years later and I'll have forgotten much of the programming language I originally wrote the code in (basically, I assume the next time I look at the code, I'll need to port it.) In instances like this, basic descriptions of what a function is supposed to do, along with pseudocode of the alogrithm with sample inputs and outputs are EXACTLY what I need - not to mention, they serve as a road map for when I'm writing and debugging the code the first time. Typically, I'll have just as much commenting as actual code for simple stuff, for anything beyond that I'll have double as much commenting as code (readable english is less efficient than clean code, so what do you expect?)
You should always look over and polish both your code and your comments before you shelve your code. If you're leading a team, it should be your code that sets the bar for good logic, commenting and formatting style. Even if you're not, good maintainable code is what they're paying you do write (I hope.) Of course, if they aren't paying you enough to write clean, commented code, then they get what they're paying for...
Proper Commenting of Code (Score:2)
What is all this about using comments to document what you are doing?
Re:Proper Commenting of Code (Score:2)
Have a standard (Score:2)
Every file should start with a preamble giving module name, version, author, and maybe revision history. Most of this can be generated automatically by your version control system.
Then there should be anything from a few sentences to a few paragraphs saying what problem this module solves and how it does it. Refer to any other documentation (e.g. UML diagrams, textbook for the algorithm) that might help illuminate what is going on.
Each function or data structure should have a similar comment explaining what it does.
Avoid comments that say "this routine is used by the Foo Function to update the Bar structure". Instead just say "This routine updates the Bar structure such that...". If the routine makes no sense on its own then it probably shouldn't be on its own.
Paul.
Location, location, location (Score:2, Insightful)
Comments are vital, but like all programming tools require judicious use to be effective.
It is easy for large comments to fall out of sync. with the code, so large comments should generally be reserved for high-level documentation of the kind one would expect to find in a literate program. Prefer a pointer (say, a URL) to a document explaining an algorithm than a block of text explaining the algorithm.
Brief comments on types and data constructors are vital where their use is not obvious. The same goes for functions, methods and procedures.
Function bodies should be small: it is better to have several small, easily understood functions (with names that clearly convey what they do) than one large block of code.
Use of formal language in comments keeps them short and clear. Compare the following:
The term 'list' can be omitted if the function has an explicit type signature (even if your language is untyped, specifying types somewhere is invaluable documentation.) Another point to note is that these comments make clear what happens when N > length(Xs) - you should specify what happens in all circumstances, even if that just means saying "if these conditions are not met then the behaviour is unspecified."
Including sanity checks in code is a useful alternative to documentation.
It is a very good idea to annotate code with the invariants that should obtain at key points.
Eschew clever code. Nobody will be impressed and it's a maintenance nightmare. And you'd better be very sure you got it right...
Don't cut corners. Include *all* the error checks. Learning how to write elegant robust code is what distinguishes real programmers from cowboys. Managing both is an acquired skill.
Avoid globals. Seriously.
State and mutable update lead to unreusability, bugs, madness and divorce. Learn a functional programming language (add smiley if that helps).
Someone once said words to the effect that if you find yourself writing a bulky comment, ask yourself if you could restructure your code so as to make the comment unnecessary.
- Ralph
Hungarian Notation (Ugh!) (Score:2, Insightful)
For the unitiated, this means that all variable names have to be prefixed with letters that indicate it's type. i for int, f for float, ch for char, etc.
The linux CodingStyle file (in the Documentation directory in every kernel source kit since who knows when) slates hungarian notation thus:
If you don't have Linux kernel sources on your machine, you can get a copy of CodingStyle here [linuxhq.com] (from the 2.0 kernels).
As a result of all this mucking about, because I tend to look after most of the dynamic memory, linked lists, and low level bit and byte-bashing operations, I end up with variable names with more prefix letters than letters in the name. I really detest this coding standard (which for some reason also forbids the underscore character on the grounds that it looks like a minus. Do you get foo_bar and foo - bar confused? I don't.
I don't agree with all parts of the Linux CodingStyle, especially the bit about brace placement, but it's a good starting point for any C coding standard. Unfortunately, ours was designed by microsoft-centric folk who think that
Ayhow, back to topic, the Linux CodingStyle also contains the distilled wisdom:
Check out how not to do it. (Score:2, Interesting)
See: How To Write Unmaintainable Code by Roedy Green [mindprod.com]
Every time I read it, I laugh from all the crazy examples of how not to do things:
eg:
16: Names From Mathematics:
Choose variable names that masquerade as mathematical operators, e.g.:
openParen = (slash + asterix) / equals;
Comments Considered Harmful (Score:3, Interesting)
Consider the different types of comment:
- boilerplate comment at the top of a file: helps noone but lawyers.
- change history comment: better use your source control tool to maintain this.
- comment before a class: does this mean the class is badly named, or too complex?
- comment before a method: ditto.
- comment inside a method: could be a smaller method screaming to get out.
Also heavily commented code is quite commonly just explaining away stupid code tricks.
Nobody's suggesting that all comments are bad, just that a lot of the time adding comments is a poor substitute for fixing whats wrong with the code. Of course sometimes its the language thats the problem
-Baz
Re:Comments Considered Harmful (Score:3, Interesting)
Yunno, I'm really getting sick of Fowler's "worse is better" nonsense trying to win back the day for "cowboy coders" who can't handle any discpline at all and want to treat critical production code as a playground.
Fowler's stuff isnt cowboy at all. It actually takes a lot of discipline to follow what he actually says in his book (writing tests to ensure that each refactoring is safe). His book is a series of recipes for how to introduce changes safely, not a rally call for changing code because you feel like it today. The Refactoring book can help people working in any methodology (except perhaps the 'Personal Software Process' and its variants, which want you to learn to write code right first time, and are less realistic for code maintenance). XP gets a mention but its not an XP book.
Meaninglessly vague. Is javadoc boilerplate?
Meaning 1 on wordnet is "a standard formulation of legal documents or news stories". Now look at this [apache.org] (code from Tomcat). See the boilerplate comment at the top? Its NOT THE JAVADOC - its the license. There are tools like jalopy which help you maintain this cruft but like I say it helps noone but lawyers.
This guy must have a massively cool source control tool that actually shows him the changelog on a per-function basis, and automatically senses and shows only the changes that are significant, like an interface change.
The 'change history comment' is the old practice of writing in a history of changes at the top of the file (not on a function by function basis as you suggest) duplicating the comment recording in the source code control system, while not necessarily recording all changes because it isnt /driven/ by that system. VSS, CVS, etc can show you the changelog externally, or you can include a $Keyword$ to get the changelog included in the comment and maintained for you. As for knowing which change is significant - developers don't know this either. The change which breaks things is the significant one and they usually don't realise they've done it at the time. Interfaces changes, while high cost, are actually less significant causes of error since they are easily caught by static checks. It is the changes in behaviour that will get you.
We don't always get to write everything from scratch...
This is true. often you'll not get to rename the methods of some dumbly named third party interface. And in this case the comment is inevitable. Note I did say not all comments are bad. I'm asking you to question them.
Another smaller, uncommented method no doubt.
Yes, exactly. If the smaller method is 4 lines long, has a blindingly obvious name, and is in the private interface of the class (often the case for extracted methods like this), the comment is superfluous.
Design by Contract (Score:2)
A couple of words, OCL
This is in the interface, rather than an implementation, and you won't get the code to the impl, so what does it do ?
/**
* Get the Bug description for the given Id
* @pre id must be > 0 and less than BugList.lastId(), the highest bug number
* @post The return must not be null
* @invariant does not change the number of bugs
*/
Well that is the comment block, not all of it because there is some OCL in there, but I thought I'd leave something for Google. The point is that the description describes exactly what the method does, it also says what the caller must do or face the consequences, and what the caller can rely upon when the method returns.
And for any one who says comments aren't required if you write the code well enough... you are a muppet. Interaction via interfaces is a basic tennent of coding,
comment the data structures too (Score:2, Informative)
Document abnormal behaviour (Score:2, Funny)
2. Use informative variable and functionnames. Short names are preferred, but make sure it's clear what you mean. If it's impractical to fit all the required info into the var- or functionname, add a comment explaining the intended purpose of the variable/function.
3. Use small functions! Split actions up into logical steps. In combination with 2 this will help make your code a lot more readable, removing the need for many comments. Like Linus says: "The maximum length of a function is inversely proportional to the complexity and indentation level of that function."
4. Document any abnormal behaviour. For instance, if you've adopted the convention that functions return -1 on errors and you have a function that differentiates between different errors by returning either -1 or -2, document what the abnormal return values mean.
5. If the overall purpose of a group of functions (e.g. in one sourcefile) isn't obvious, add a general comment that explains the big picture. Code is much more readable if you know what it's trying to do.
Work from the top down (Score:2, Interesting)
No matter how clear you think you made the name of the function, there should be a comment explaining what the fuction is supposed to be doing. If the function accepts a lot of flags or variables you should briefly explain what they're each used for.
Knowing what the function is supposed to accomplish is a big step forward, even if there are no other comments at all.
If you're still willing to keep at it, start commenting the big blocks of code in the same manner. What are you trying to do with this loop? Why are you testing for these cases in this if statement, and if it succeeds, what are you trying to do inside of it?
Always go in favor of more comments. I would rather have to skim by a dozen comments that I don't need to read than be left hanging for the lack of one comment when something goes wrong.
And finally, always use whatever comment system your source control program uses! Even if it's just "I did some stuff to fix some problems with A," because if I later find out that a particular case of A is broken, I don't want to have to do a diff on every single code change made since the last time I knew that case of A worked.
My favorite comments (Score:5, Funny)
i++; //increments the variable i
I think that they are unclear and do not properly explain the situation. Remember, you're writing so people can UNDERSTAND the code, not so that you can impress them with how smart you are. Instead, strive for a comment like this:
i++; /*changes the value stored in the space referred to by i to be the sum of the old value stored in the space referred to by i and the constant 1. Note: In C, this may cause what is known as a "silent overflow" if the value is too large, and go so far as to make a large positive value into a larger negative one. Oh my!
This way, people who read your code not only understand your program, but all programs. I really think that each function you write should repeat a semester's worth of computer science theory and programming practice, so that anyone who reads your code will learn from it. Remember, not everyone knows idioms, and why should they? And since we all write open source on slashdot, many novices are going to have their introduction to any computing environment by looking at the code you write at any point.
Your most humble and obedient servant,
Dan
Some examples of bad comments (Score:2)
a = b;
/* this function calculates theta. */
float theta(char **p, int d, float *(*fn)(int))
{
...
}
Two basic rules (Score:2)
One way of doing this is to have a comment block introduce each class and each function. If these comments are not in a standardized format, at least make them consistant. If you're using a non-obvious algorithm, this is where you should describe it, in full. If it is spectacularly non-obvious, provide a reference to a separate doc. And if your project has created design documents prior to coding, provide references back to those docs.
Obviously, the way code is "chunked" in item (1) has a lot to do with how it gets documented in item (2), and vice-versa; I put them in that order because it made it easier to explain, though in practice much of (2) is done before (1). But the two have to be taken as a whole and ultimately completed as a whole.
I don't know how many times I've seen comment-as-you-go code where the comments disagreed with the code, and it wasn't clear just what a function was trying to accomplish. But if I understand the goals of a piece of code, and reasonable care has been taken in naming and organizing it, in-line comments just get in the way.
Formatting (Score:2)
Use inline comments sparingly. Write complete, descriptive sentences at the block level. It's also good to put blank lines before and after comment blocks.
Commenting "null" code (Score:2)
Basically someone had been going through code and found an entire subroutine commented out with the rider "This doesn't work". The original poster went on to say (s)he'd initially missed the point and thought the commenter was dumb, until the penny dropped - this would be a massive time saver if someone else thought of the same routine.
I have to admit, I'm not sure if this commenting practice would have occured to me - until I read this I'd always deleted broken code. It's definately something to bear in mind next to you waste a few hours working on a flawed algorithm.
Comments are only a part of the answer (Score:2, Insightful)
You should seriously consider
The problem with comments is that they explain what the code does, but all too often the "why" - the structure of the program - is not obvious by looking at the comments - it's like trying to work out a streetmap by looking at the names in the phonebook.
I took over a large project from a major consulting firm; much of the code was immaculately commented, but the overall structure of the design was almost impossible to fathom; the documentation was out of date and incomplete, and everybody had a slightly different view of how things worked. Whenever we fixed a bug or made a trivial change, we'd hold our breath just in case the trivial change had unforeseen consequences somewhere else in the system. A simple class diagram and database schema would have been more useful than most of the comments. Unit tests would have saved us literally hundreds of hours of pain...
Code Complete, a book by Steve McConnell is a great read on this subject; I also recommend "Agile Development" by Cockburn.
Tracing (Score:2)
I find that the trace calls in the code are often as good as comments, in that someone browsing the code could use the traces to work out what's going on.
e.g.
for(lc=0;bytes_left>0;lc++)
{
trace("In main parsing loop, chunk %d, %d bytes remaining to process",lc,bytes_left);
}
... tells us the purpose of the loop, and the purpose of two variables. Clearly putting a real
I think even if I weren't tracing, I would place comments in pretty much the same places.Of course this isn't all the commenting I do -- there are certainly comments required above and beyond these, such as detailed descriptions of what a function should do above the declaration.
WHY not WHAT (Score:2, Insightful)
is being done rather than WHAT is being done.
If the code is written clearly, in sensible size functions and with
meaninful variable and function names it is easy to see what is happening.
It's the WHY that often escapes even the original author some
years down the line.
Things to bear in mind (Score:5, Insightful)
Here's the rules I use:
Favor Code Clarity Over Comments (Score:5, Insightful)
This is poorly commented code (despite the fact that the comment is clear and accurate):
aClassName = aTask.getUiInitializerClassName();
if( aClassName != null && ! aClassName.equals( "" ) ) {
}
This is well commented code (despite the fact that there are no comments at all):
initializerName = aTask.getUiInitializerClassName();
boolean isNotNull = initializerName != null;
boolean isNotEmpty = ! initializerName.equals( "" );
boolean definedForThisUi = isNotNull && isNotEmpty;
if( definedForThisUi ) {
}
Of course, this doesn't work in all situations, but I find that I can improve the clarity and accuracy of seventy to eighty percent of my commentary this way.
You are a moron (Score:3, Interesting)
2. You introduced a bug on line 3 (null pointer dereferencing).
Yes, I have personally seen code like it and I wanted to shoot the fucking idiot who wrote it.
Golden Rule (Score:3, Insightful)
The most important thing wrt to commenting code is to put yourself in the reader's shoes. What would that reader need to know that's not obvious from the code? One useful exercise is to pretend that you're leaving your job and you're doing a brain-dump for the (reasonably bright) person who will inherit your code. Your goal is to anticipate every question they ask or suggestion they make, in the form of a comment. If they're likely to ask what something does or how it works, add a comment. If you add code to fix a specific bug then add a comment; obviously you didn't recognize the need for that code at first, or else there wouldn't have been a bug, so the next person probably won't either unless you comment it. If they're likely to say "this would be better if xxx" but you already tried xxx, put in a comment that says "we already tried xxx but it didn't work because..." IMO that last is the single most useful kind of comment because it saves someone from going down a blind alley. BTW, the same "role-playing" approach works really well for specs too.
Another important skill is knowing when not to comment something. If it's blazingly obvious what something does and how/why it does it, don't comment it. If there are too many comments, the person reading the code will often decide that reading the comments is a waste of their time and they'll just start ignoring them. Then they'll miss the one comment that really does matter. If you must be verbose in your commenting, at least use some sort of visually obvious marker for really important "you'll break it if you ignore this" kinds of comments, to distinguish them from the less important stuff.
Lastly, don't be afraid to spice up your comments. Be totally candid about stuff - yours or someone else's - that you think is brain-dead. Make wisecracks and in-jokes, within the bounds of good taste and brevity. People are more likely to read your comments if they can occasionally get a chuckle out of them. They're more likely to enjoy working on your code, and speak well of it/you when asked. These are all good things - for you, for them, for your employer or client. Coding can be dreary enough without robotic comments.
My list (Score:4, Interesting)
One purpose of comments is to explain the code to another engineer (including oneself in the future). Another purpose is to demonstrate the code works, whether an informal argument that the code does what it should or a mathematical proof. These two purposes have different needs.
For the former case, standard writing rules apply. Decide who the audience is. I often figure the audience is an engineer who knows the type of programming at hand, but doesn't know what is done by this particular code, and may or may not be familiar with the product, depending on circumstances. Knowing the audience tells you what assumptions to make and what has to be explained, either by prose or by giving directions to reference material.
Write complete, grammatically correct sentences. This goes a long way to making comments comprehensible. Sometimes a little phrase won't be understood because the reader can't fill in the unwritten parts, or because there's ambiguity in the wording. It is okay to use short phrases when describing objects being defined or declared (e.g., "number of links to this object" or "dollars owed this customer), but keep the context in mind. Introduce the compound object with sentences where appropriate.
"Dollars owed this customer" reminds me -- use units. Don't write "Money owed this customer" or "time since last update." Specify seconds or milliseconds, not time. Document how the object models whatever it is modeling. That may be a physical thing like time or a conceptual thing. E.g., if a pointer connects one object to another, document the relationship that represents. If a "debt" class contains a pointer to a "person," don't document it as "person associated with this class." Document the relationship -- this particular pointer may represent the debtor, the creditor, the escrow agent, or somebody else.
Give context. I have seen thousands of modules that just leap into code with no explanation of what they are. Even if the comments say what a function does, a reader might not really understand it until they know what it is used for. Document where the code fits into the bigger scheme and what it is used for. Give the reader context so the purpose of the function makes sense. Even if a complete mathematical description of a function is given, so that the reader can precisely predict its behavior in every situation, it might not make sense to the human mind until they have a mental image or model of it.
For the second purpose, demonstrating the code works, explain how the code implements an algorithm. It's not enough to explain what the steps are doing; you need to show how the total result comes out of the algorithm, unless it is something simple or familiar. E.g., a formal description of the long division taught in elementary school would generally be incomprehensible. "Find the largest digit d such that d times q is less than r[i]. Subtract d*q from r[i] to get r[i+1]. Append d to output..." Nobody seeing that for the first time would understand what it is doing, even if all the steps were clear. Even if you explained each step and explained the result, it won't be clear to some readers how the steps produce the result, so explain that.
Document alternatives that weren't chosen, and the reasons why. If you were tempted to implement algorithm X but found you had to do Y because some error might occur, record that information. Otherwise, somebody working on the code next year might see your longer code for Y and change it to X without realizing the problem.
This isn't intended to be a complete list, just what occurred to me at the moment.
Knuth - Literate Programming (Score:3, Insightful)
Comments by counterexample (Score:3, Informative)
Take a look at these files [uiowa.edu]. This project is basically an example of what not to do. It's faggotted up like a twelve-year-old schoolgir's notebook, to borrow a phrase from The Onion. In particular,
That should be obvious from the "public static void main (String argv[])".
Wait till you've almost forgotten it (Score:3, Insightful)
Re: Comments are evil. (Score:2, Funny)
Unless the code is Perl ;)
Re:Comments are evil. (Score:3, Insightful)
Sorry, but that's just not true.
You need fewer comments if your identifiers are well-chosen, certainly. But I've never seen a significant piece of code that would be adequately described by well-chosen identifiers alone.
Re:Variable Names (Score:2, Insightful)
They don't have that funny bone, when the code is going to be in production software, and maintance by others.
It's a professional image thing...
Re:Variable Names (Score:4, Insightful)
The same goes for 'amusing' comments in the code, or CVS logs.
For your sake in the future, and your coworkers' sake now, please stop it.
PS. Did I mention how fucking annoying it is?
Re:Variable Names (Score:3, Funny)
Re:Variable Names (Score:5, Insightful)
Querying the DBs directly showed that the data maps were works of pure fantasy in several spots, or would lead to outright data loss if followed precisely. In a fit of pure...creativity...I ended up setting a "$workAroundFuckups" variable, and in the sections where it was needed, had a false evaluation do precisely what thee datamaps said, which would corrupt data. If the variable was true (ie, non-zero), it would work correctly, which meant ignoring the data maps and doing what was needed to have the data be entered correctly.
I ended up getting moved to another customer (due to the limited resources *we* had, not because of my creativity), so I don't know if the remaining folks on the project removed it after I left. When I added it, I explained to them precisely why I'd added it, and since they'd had similar experiences with what we were given to work with, were behind me 100%.
This wasn't even the *only* part of the project which was FUBARed, but it was unfortunately what I spent many a 15+ hour day dealing with, so I was rather familiar with it. Had I access to the server that *read* the data and used it, I probably would have just gone in and redesigned everything "for free", just to avoid having to deal with such a horrible layout.
This is also the client where, after a few months of an irksomely out of sync clock (off by 12 hours...made figuring out when something happened a bit of a PITA), I finally went in and set the damned clock to the proper time. Not surprisingly, the same folks who made that wonderful novel for us were the ones admining the dev server we were working on. AFAIK, no one ever noticed that the time suddenly became "correct" either.
Re:Variable Names (Score:5, Interesting)
Thing is, there's two essential things that a reviewer/maintainer has to understand about a program: what it does; and why it does it. It should be possible to work out the first one of these just from the code, so long as the variables and functions are named sensibly. The second can be worked out from code with some effort, or the coder can add comments to explain why they're doing things that way and make it easier for maintainers.
But if someone has deliberately given all the variables names which don't reflect what they do, then it's utterly impossible to work out what the code is doing, and it's therefore also impossible to work out why it's doing it. So the code is unmaintainable - it isn't possible for anyone else to pick it up and work out what it does, except with massive work. If in 6 months time your company says "oh, we've got this code we can use with slight modifications, let's quote 1 month to do this contract" and then they find out you've made the code utterly obscure, then they'll crash and burn. And if that happens, the company *will* fire (or at least formally discipline) the person who wrote the original code, bcos they've been grossly negligence in doing their job. And you can kiss goodbye to any reference from them, so you'll be SOL in finding your next job.
Grab.
Re:Variable Names (Score:3, Insightful)
for (i = 1 ; i ARRAY_SIZE ; ++i)
{
do_something_to (array [i])
}
Why isn't it doing something with element 0?
Now look at these two fragments
/* Do something to all elements in array */
for (i = 1 ; i ARRAY_SIZE ; ++i)
{
do_something_to (array [i])
}
and
/* Do something to all elements in array except */
/* the first one because... */
for (i = 1 ; i ARRAY_SIZE ; ++i)
{
do_something_to (array [i])
}
Just by adding a one line comment, a bug has been exposed, or the maintainer has been prevented from inserting a bug in the second instance.
As a maintainer, I'd want to be able to see what the code does (well set out, good structure, descriptive names etc) and what the programmer meant it to do, i.e. good comments.
Anybody who puts jokey unhelpful comments in their code should be aware that these will inspire feelings of hatred and extreme violence towards them in the maintainer who has two hours to fixe the air traffic control system before the 747s start falling out of the sky.
Re:Variable Names (Score:2)
Re:Simple rule of thumb (Score:4, Interesting)
Nice idea; never works in practice. The reason is that what you think is easy to understand is not always what other people think is easy to understand.
The code you are writing now might have to be modified in the future by someone just out of university which means, generally, someone with very little experience. Your red-black binary tree might be "easy to understand" for you and a novelty to them.
Also, mature highly-factored, optimised code that has been improved over several years can be very hard to follow even when the original code was quite straight-forward (but perhaps too slow).
Finally, as a philosophical point, source code is supposed to be terse in comparison to natural language so it should take longer to describe the code in your own language than in the programming language.
TWW
Re:Simple rule of thumb (Score:2)
Quick explanations are rarely precise explanations when programmers are involved.
Anyway, keeping documentation longer than the code encourages shorter code more than it encourages rambling text, unless you know programmers that like typing more than I do.
Short code with a good explanation is always better than long code with poor explanation. In fact, short code is always better, period. Every line of code beyond what is needed for the task should be rooted out; it is a source of bugs and inefficiency.
TWW
Re:Literate programming (Score:2)
I have "Literate Programming" by Knuth, but there always seems to be something more important coming along that I need to read "first".
Re:Coding Standards (Score:3, Funny)
Phew, I thought I was alone. I'm glad it makes sense to someone other than myself to actually have the braces line up vertically.