What is Well-Commented Code?
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."
I sometimes get, uhh..."creative", before I program. End up with variable names like "$iHateThisProgram" and "$godFinWorkAlready"
Anyone else experience this phenomenon?
--------------
David O.
I can absolutely recommend a book called Code Complete. Yes, it is published by Microsoft, but it is an invaluable language-agnostic guide to writing software that includes heavy doses of common sense regarding commenting, coding styles etc.
I Have to scan through code regularily and the biggest problem is the variable names. I realize that they must mean something to the coder but to us maintainers they're most times akin to Sanskrit. Function(method) comments are nice too.
In a time of universal lies, Telling the Truth is a revolutionary act - George Orwell
ie,
while (1) {
}
Code Complete by Steve McConnell
Writing Solid Code by Steve Maguire
I have been pwned because my
The best comment is the code.
I guess the only real solution is to give a specific coding standard for every project. Before you begin coding, make up a standard that every developer has to follow, for comments, code layout, etc.
h tml
A good standard for C++:
http://www.possibility.com/Cpp/CppCodingStandard.
The practitioner of literate programming can be regarded as an essayist, whose main concern is with exposition and excellence of style. Such an author, with thesaurus in hand, chooses the names of variables carefully and explains what each variable means. He or she strives for a program that is comprehensible because its concepts have been introduced in an order that is best for human understanding, using a mixture of formal and informal methods that reinforce each other. Donald Knuth. "Literate Programming (1984)" in Literate Programming. CSLI, 1992, pg. 99.
This post was compiled with `% gec -O`. email me if you need the sources
While I'm personally of the opinion that the level of comments that's acceptable depends a lot on the purpose of the application and the number of people working on the project, a friend of mine learned a very good ( if slightly anal retentive ) coding style from reading angband source code.
Maybe not for everyone, but you may want to try it.
I only work with Perl. When I'm looking at someone else's code all I ask is that they outline the basic function of a particular section of code so when I need to change/enhance/debug something I can find the right area to start looking as quickly as possible.
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.
A fool throws a stone into a well and a thousand sages can not remove it.
Good code comments should describe the intention of the code. Write them *before* you write the code in a function/method to describe it's purpose. This will make you think exactly what you want it to do, and will allow for others to find/fix bugs easier when the implementation doesn't meet the intention.
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.
I use doxygen++ for C++; it's great
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/
Well commented code should definitely contain a liberal smattering of four-letter expletives, eg:
// 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.
My style mini-guide
Essential items of any source code:
* Easily readable function and variable names
* Functional comments, expressing intent
* Large indent, making blocks obvious
Opening statement and closing brace of a block are on the same column for fast correlation.
* Consistant naming, all lower-case, _ for space.
Some of these are contentious at the moment, see the link above for further details on why I believe in these. Regarding comments strictly, as I said it is commenting *intent* that is important. Commenting function is pointless, if you need to comment function your CODE is broken. The commenting of function is one of the leading cause of "lies" within code, that is, some aspect oor another that leads a reading programmer to assume to code operates in a manner which it does not. Examples of this are incorrect comments, badly named variables, and to a lesser extent badly scoped variables.
So, commenting is not just a positive, it can cost you more than no comment at all if it is incorrect, sending the maintenance coder on a wild goose-chase through perfectly fine code looking for a bug that is overshadowed by an incorrect comment.
Tools like javadoc, or maybe better in your case doxygen can really help when it comes to commenting code... the idea is pretty much that you place a documentation comment before each function, or class, and so on, which usually makes the entire thing much easier. Having done that, I've found that only a few more non-obvious parts have to be commented within the actual functions.
Tomorrow will be cancelled due to lack of interest
I guess most of you have seen this page on how to writing unmaintainable code before, but I'll post the link anyways:
click me
A little simplistic, but a good start, IMHO
TWW
"Encyclopedia" is to "Wikipedia" what "Library" is to "Some people at a bus stop"
Taken from a Slashdot reader:
Real programmers don't comment. It was hard to write. It should be hard to read.
Well, according to Stroustrop, overloading whitespace and using single-character unicode variable names can help increase clarity. :)
-- My Sig is a P228.
With 50 people all writing code for the same project going through this process, you shouldn't be able to tell who wrote which bit.
The disadvantages to this are that it makes coding a bit robot-like - but hell, all the work was done is design anyway. People might also say that typing comments takes too long - but so does having to work out what the code does every time you look at it - instead of it staring you in the face. If this isn't what you want to hear, then try simply having a block comment for every code block, and a header at the top of every source code file. You should this way have as many lines of comments as lines of actual code. This is not, despite what others may say, a bad thing.
This book is a must-read on programming style. It also contains a perfect chapter on how to comment the code clearly.
Company wide coding standards are implemented where I work, and whilst many people see them as an affront (i.e. "I'm already a good programmer - why should someone else tell me how to program) it does mean that code from other people is usually pretty easy to understand.
Here are some of the key points in ours:
function headers:
put a description of the function, and what its inputs/outputs are/do, the original author and the date of creation. Anyone who modifies this function in the future (beyond very basic changes) should add their name and the current date, plus a quick description of what they changed
variable naming:
adopt a standardised and logical hungarian notation for the variables, and try to avoid abbreviating when the full word would do. "nCount" is far more descriptive than "cnt"
Other things, such as always including { and } in C, and putting them alone on their own line makes the code much easier to read (though longer, but I'd rather read long meaningful code to compact confusing code) and putting plenty of bracketing in equations
Help me! I'm turning into a grapefruit!
When I was at Uni, I got marked down in a class once for over commenting my code!!!
:-)
I include a variable definition block at the top of each function describing what each variable was for.
Each function got its own description and then comments were in the code when I was say, performing some test.
Still, that is University for you
I was most impressed by the advice Rob Pike gives on commenting code. If I remember correctly, his main points are: write code so that it is uncluttered and acts as it's own comment, never paraphrase the code itself, but rather explain metastructures and relations (otherwise you are more likely to have outdated comments that were redundant in the first place; a line is more likely to change than the overal logic). Keep both comments and code concise and clear. And call it complex_multi_word_variable, not ComplexMultiWordVariable, for readability's sake.
...and this lie crawls out of its mouth: 'I, the state, am the people.'
My vote is that everyone should use a CRC (Class Responsibility and Collaboration) style (wherever sensible). I want to know why a class exists and where it is to be used and what is its purpose - down to the level of detail of behaviours of individual methods. Thereafter I prefer to see concise and compact code and shy away from comments reading as if a chatty soliloquy (which often bears little or no correlation to the code - especially after it has been "maintained" by a few people!)
Coding standards, to me however, seem to be quite a red herring... all code should be correct, coherent, compact and with a similarly crystal-clear specification. Most "coding standards" I've encountered have concentrated on fine-grained stylistic issues while ignoring the wider goal of concise clarity.
a bad comment would be something like
for(i=0; i
Obviously anyone who understands the language itself understands what the standard statements do, and anyone who doesn't understand the language probably doesn't have much reason to follow the program flow line by line.
Good comments are a level or two more abstract, and cover the medium-to-big picture of what functions and chunks of code are there to accomplish. Comment any *unusual* pieces of code, and any code that is doing something tricky, "clever", or simply less than obvious. Use code as a sort of "caulk" to fill in the holes of understanding in your code. Don't narrate the entire program line by line, but also don't hesitate to comment where the code is unclear.
If the code is consistently unclear, it may be an indication that your code should be more readable overall.
I also have seen my share of other people's code.
// increment i
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.
-- In the beginning was the WORD, and the WORD was UNSIGNED, and the main(){} was without form and void...
It's been quite a while since I wrote any significant amount of code but after spending far too many years cutting code too early in the development process I eventually woke up to the fact that coding is the *last* thing you do (apart from testing and debugging that is).
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.
For big projects (and only big projects) using the Unified Modelling Language and especially the Rational Unified Process is very useful.
Rational has quite a few tools which (when used correctly) allow to trace what class is responsible for which business case.
Having done coding and commenting for more than 20 years, the most successful I've found is this one:
// Initialize for the loop
// Set all characters in
// parameter s to space
Group several lines of code and comment them together with one or more lines of comments before the code. Example:
// This is an example of how to
// comment in an easy way
function doSomething (String s) {
int i=0;
int j=0;
while (condition) {
s[i] = " ";
i++;
}
}
The coding team I work with have some standards that the analysts and other code reviewers try to stick with.
At the top of each 'significant' method, we whack a comment block such as this:
Name
Description
Date
Pre
Post
Input Params
Output Params
Returns
( and obviously fill it out ). One beauty of this is the description. If you can't describe your unction in a line or two, then your function probably needs to be broken down a bit further. It makes it a bit easier to follow the code if there's a nice header block to describe each function.
A naming standard for variables is good too.
We tend to follow a variant of the Hungarian notation ( ?? ) which has a single character to define scope ( local, module, global ) plus a character to denote variable type ( s for string, l for long, i for integer, o for object )
So, you get a variable like liCounter ( a locally declared integer for counting ) or goCounter ( a global Counter object )
Anyways, everyone has their own standard, the trick is, come up with a standard, and stick to it. Try to enforce ( encourage! ) the use of the standard. Even if no one else wants to, stick with it yourself, if you tend to maintain the code you write ( as opposed to someone else ) at least you'll be able to follow it !
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:)
I find that the use of a folding editor which demands fold comments (i.e. nopt JEDit style) very valuable. If you get used to folding up your code, then you are forced to put enough comments in the body to make it readable.
There should be Javadoc-style header commments on any function more than five lines long (and most shorter).
If you have both of those, you won't get much better for commenting.
Projects should have coding standards, and people ought to conform to them even if they don't personally agree with them. Code written to one standard and modified to another is worse than either. If you can get automated formatters, tune them to your house style then use them.
It is possible to be too verbose, but it is much easier to be too terse. Err on the side of verbosity.
Standardise abbreviations. Is "Length" given in full, abbreviated to "len" or to "ln"? Whichever you do, always do the same thing.
Consciousness is an illusion caused by an excess of self consciousness.
comes this advice:
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.
--- Hot Shot City is particularly good.
are the best way to comment it all.
//end if" or something.
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.
"Wireless : LAN
Personally, I like documenting backwards. Start with the requirements, work to the architecture, then get into writing PDL (Program Design Language). Essentially, you write out as detailed instructions on what the routine does as you can, without getting to the nitty gritty. It describes the intent of the code, not the code itself. It morphs into excellent comments when you expand it out into full code, and it also has the nice little advantage that it's at a high enough level that it's applicable to multiple languages (if you should desire to switch).
WannaBeGeek*Girl*? Girl? What marvelous creature is this you speak of as "Girl"?
The best commented code is literate programming code. There is no better.
"The first thing to do when you find yourself in a hole is stop digging."
You may want to check out FreeBSD's style(9) manual page. FreeBSD uses this in the kernel, and reading most kernel sources usually isn't a problem for me.
I'd second this, I started coding in FORTRAN/RAMBOTRAN many years ago and now use c/c++/php. The book is a very good read with some good anecdotes and worked examples. The best bit is that it is fairly language independent.
Good code speaks for itself, so the best comment is a not written (ie. dead) one ;)
Beware of Programmers who carry screwdrivers. -- Leonard Brandwein
It all depends on the person's personaltity and such. Personally i comment code that has taken me a while to code or figure out. i figure if i can figure it out than others can, if not then i comment for my self and figure if others are smarted than they wont need my commments. /*/* This code explains the fundementals of my commenting process */ this is my explanation of my commenting */
If we're in the mood to split hairs... then declaring variables as
;)] ... char *foo, *bar;
type* var1;
is rather misleading in itself, ie: char* foo, bar;
Whilst most people can instantly tell that it's meant to be a pointer to char and a char, it might not always be obvious if the programmer wanted two pointers, or a pointer and a char.
Better to place the * with the variable name [imho
Personally I think the linux kernel is very well documented, at least the scheduling part, which is what I've looked at. Linus has a style of inserting huge comment blocks that explain exactly what's going on, then he'll have a page of code that does it, with little or no comments.
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.
this is my sig.
Sheesh, so much for examples... the code was not intended of course to be specific... rather it was to act as glue to the comments.
Now, where's my dictionary.
For instance, the code above has the following:Yet personally, I like code formatted in this style:I find that when you get a bunch of nested blocks it becomes easier to follow.
When I see an opening brace as the first character, it's a reminder of the start of a nested block and I know I can skip to the close brace if I don't need to go into that block, with the blank line helping to easily spot the closing brace.
That Jesus Christ guy is getting some terrible lag... it took him 3 days to respawn! -NJ CoolBreeze
In order to keep a project simple, I follow a few guidelines:
:)
- Avoid complex functions. If your function seems to be too complex, try to swap out some code into another function.
- Document the function's parameters and the values it return.
- Flame/Kill/Bitch me for that, but I tend to create some nice graphics which show the complete project with abstract components, so you get an impression of the whole project BEFORE YOU START CODING. This makes it easier to decide which objects/functions belong to which module. See http://www.monday-rec.com/timo/rs404/rs404.html (hope that works on every browser
Hope that helped a bit.
-Timo
Every problem has a solution, but every solution creates new problems.
"What exactly is well-commented code anyway?
Wow, this is like the first time I've seen some make the right anyway/anyways word choice at the end of the sentence. This just made my day. Now if people would start making the correct its/it's choice, I could die happy at the end of my life!
Screw comments.. if they can't understand my code, they don't deserve to edit it.. It goes both ways.. Hail the spaghetti coders!
"Make it idiot proof, and someone will make a better idiot."
It's real simple. If the reader can't tell what the code does from reading it, either it's written badly, or the reader is incompetent. In either case, comments won't help. If I see too many obvious comments, it's a clue that the author was clueless and I should probably just throw the code away because it will cause more trouble than it fixes.
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.
http://rareformnewmedia.com/
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 :-)
One thing that is hard to do is find a reasonable balance between commenting code, and bloating the file so that it is hard to find the code. Anyone else have this problem? For instance, sometimes even with syntax highlighting, getting through all that wordy commentary is like trudging through the haystack looking for the needle. Here is where tools matter.
:-)
First, use a good documentation program like doxygen or doc++ (C/C++) specific. Then a user can see the highlights of the code functionality in html, away from the code. This solves much of the overview type of code reading.
Second, use well-thought out function names and variable names and be consistent. This is often at the cost of space, but even if you are writing code just for yourself, I found it helps tremendously.
Third, use short, descriptive, comments to point out algorithm purpose, especially when it took you time to think through it. Try your best to not interrupt the flow of the code by putting comments on the end of the line.
Fourth, on my wish list is a tool that I have not seen. That would be some kind of comment compressor, like you do with expanding directories into trees on a GUI file manipulation program. Emacs programmers -- are you listening?
Finally laying out code in a consistent manner (the right tool is indent here) really helps. Many styles have evolved because they provide visual feedback and cues about what you are seeing. Having and using a consistent style helps future mainters use those visual cues as they parse through your code. These cues can be more effective than comments because they are succinct.
Guess what? I got a fever! And the only prescription.. is more cowbell!
Good documentation contains formal specifications. Although most "programmers" will not agree, formal specifications provide the best way to document your code. First of all, they tell the user exactly what the software should do or should not. Secondly, writing formal specifications forces you to think about what you're doing, and prevent most bugs and design errors, even before you write the actual code. Another advantage is that once the specification is written, the code and the test classes can be written independently, which should result in better tests because the specification says what a method should do, so you don't have to guess it.
On top of that, it should contain a description of what it (a class, package or whatever) should do, and class diagrams (a picture can say more than ....).
For an example, look at the org.jutil.java.collections package of the Jutil.org project. The math package doesn't contain formal specifications yet because not all functionality is present to write them (numerical mathematics ...).
If you want to write object-oriented software, read "Object Oriented Software Construction" by Bertrand Meyer, it's a must read.
Have a look at CWEB by D.E.Knuth. It shows a way of writing C / C++ / Java code that can really be understood.
Apart from that, the use of syntactically more rigid programming languages like Oberon reduce the chance of obfuscated code in the beginning.
I find the best way of commenting is to keep it sparse. Functions or blocks that do things in an unusual way get a thorough explanation on top - by 'thorough' I don't mean 'every detail' but rather the purpose, the algorithm and why I did it this way.
...'). Those two pratices are amongst the vilest Microsoftisms, and they make the code next to illegible.
Other than that, keep a rigorous indentation structure, use short, simple names and don't make 'cute' code: no MixedCaseNamesForGodsSake, and no unnecessary white space (like 'for ( i = 1 ;
I explain what each function is supposed to do, along with any assumptions I'm making and any desired side-effects that the coder should expect. If I'm using algorithms beyond a basic for loop, I'll stick pseudo code with example inputs and outputs in the comments as well.
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...
I thought that commenting was only supported to prevent a block of code from being compiled (or even better, dozens of little fragments of code).
What is all this about using comments to document what you are doing?
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.
You are lost in a twisty maze of little standards, all different.
The chapter on style, from Bertrand Meyer's book Object Oriented Software construction, is available for download in PDF. It has some good, general rules for readablity and format.
The reality of free software.
I like to see comments describing the data structures. If I know what variables mean it's usually not too hard to figure out what a piece of code does. It's much harder to do it the other way around.
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
There are other, simpler WEB variants as well.
Nuweb works with basically any language.
Noweb is a bit older and written in ICON.
The main advantage of these WEB variants is that they use LaTeX rather than TeX, and TeX is far too complicated. The disadvatage is that WEB and CWEB "know" about the language and can give more information about things like the variables and functions, where in a generic literate programming system, this is either not possible or must be done manually.
- Serge Wroclawski
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 (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:
See: How To Write Unmaintainable Code by Roedy Green
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;
If code has a lot of comments, that is either an indication that it isn't clearly written, or that it contains unnecessary comments. The first is an indication that there is a problem with the code itself, the second impedes readability (but can usually be remedied by hiding the comments in the editor).
This has come up before - in Martin Fowler's book, "Refactoring", he makes the controversial claim that sometimes comments are indicative of a need to change the code.
:)
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
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,
An Eye for an Eye will make the whole world blind - Gandhi
In high energy physics, lots of code is written for very large experiments such as RHIC and LHC. A lot of it gets done using Root(root.cern.ch), which is a C++ framework for building stuff and also an interpreted interactive data analysis package. They use the Taligent rules for naming and the K&R rules for style:m en tRoot/1.0/Docs/books/WM/WM_63.html#HEADING77
pcroot.cern.ch/TaligentDocs/TaligentOnline/Docu
I have encountered lots of code, with and without comments, written by people who have mastered the finer points of their chosen programming language and, more often than not, their code is all but incomprehensible to us mere mortals.
Some languages cope with this better than others. C/C++ lends itself to instant double-dutch in the hands of an "expert" coder whereas VB tends to make sense despite the efforts of the coder.
My rule would be "code for the human reader". The machine will cope with the code however well or badly it's written but humans can be left clueless.
I would also echo the comments above which call for comments denoting *why* you're doing something rather than *what* you're doing. I can almost always figure out the what from the code itself, why is a different matter.
It is not only executeable code that can benefit from comments. In particular any numeric fields should have a units comment (e.g. m or m/S). It can be quite time consuming to deduce the units from the code.
1. Adopt some set of coding conventions. For instance, always return 0 on success/in the normal case.
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.
If there is hope, it lies in the trolls.
when you still know what is does after 6 months!
this sig has intentionally been left blank
in C++... let's find some of those old IBM keyboards with all the symbols on them...
Too many comments can be just as much a sign of bad code as too few. When a function or methodis filled with paragraph-long comments explaining what it does, that's often a sign that you should rename some variables, or factor out parts of the work into separate, well-named functions or methods.
Don't be afraid of having long, descriptive names. They go a long way towards making the code more clear without using comments.
Sometimes, even if you break a function into several subfunctions that it calls in order and which are called nowhere else, that can help readability, as long as you draw the boundaries intelligently.
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.
This Space Intentionally Left Blank
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
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.
Seen in an actual program...
"//This code is not commented so that you may
//comment it to your own liking.
//plz do not send me back commented code!"
I don't know weather to laugh, or cry.
My new top secret key -> C>N|KB
Document the design decisions in the comments.
Any time you code, you make many large and small decisions about why the code should be a particular way, and about why it must not be some other way. These are rarely deducible from the code itself and you need to write them down.
Code is very fluid these days, because coding is cheap and easy compared to specification, testing and external documentation. People refactor because they can, not because they must, and because it usually improves things. Recording the design decisions and underlying reasoning protects your code from ill-informed refactoring.
i++; /* increment i */
/* save the value of b */
a = b;
/* this function calculates theta. */
float theta(char **p, int d, float *(*fn)(int))
{
...
}
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.
It uses parameters in a way that does not make sense often.
So, before calling one of those (more obscure) functions, I copy/paste the list of valid parameter just before it.
This way, should I need to understand the intent of the call and wether it is valid or not, I just need to look the comment. [over the last two months, already saved me hours of debugging!]
Caveat: This works only if the function is seldomly called in the code. If called often, you're better off memorizing it.
This page http://www.openbsd.org/cgi-bin/man.cgi?query=style &apropos=0&sektion=0&manpath=OpenBSD+Current&arch= i386&format=html is a good start.
Any/all companies that write or edit code should have documents like this. Then again I also think all code should be peer reviewed and tested before it's considered stable for use. But then again I'm an idealist and know the world works exactly the opposite way.
"Survival of the fittest Max, and we've got the fucking gun!" - Pi
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.
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.
UNIX? They're not even circumcised! Savages!
here's an example from an expert. Dennis Ritchie wrote the following code in the Sixth Edition of UNIX back in 1975:
but in all seriousness, i have found that the two most useful tips when commenting code are as follows:Good commenting should describe your objectives and the algorithm (i.e. procedure) you will use to reach those objectives. So like algorithms it should be independent of any language (including C). If the comment is enough for someone to re-implement the procedure in another programming language, then it is spot on.
To this end, having experiences with many languages helps. It also follows from this, that good comments will, in effect, teach someone how to program in a language. It also follows that comments should not include language dependent phrases like 'functions', 'pointers', 'int' or variable names. It also follows that blatent comments like
// Increase the number of sales
number_of_sales++;
are not superfulous. Comments like these also make it convenient to someone jumping to the middle of code, see what the purpose of each Variable is, without having to search for the declaration, wherever it may be. This all flows from the tutorial nature of this kind of approach to commenting.
An excerpt off of a web page from a old college professor of mine states:
When should you comment.
You should comment your code as you are writing it, when what you are doing is fresh in you mind.
If you wait to comment it after everything is written, you may have forgotten why you did something a particular way or what a complicated section of code does.
What should you comment.
It is possible to over comment code. Every line of code does not need a comment.
The key things you should comment are:
Put identification comments at the beginning of every source code file.
Each function, including main, should have a comment before it stating its purpose, even if it is a one line function.
Anytime you are doing something complicated in your code. If you can't glance at it and know what it is doing, comment it.
Anytime you are doing something new. I hate to learn things twice, so when I use a library function that I have never used before, I put some extra comments in the code, so I don't have to go look up the function the next time I need to use it.
He is a wise man, so I still use his page as reference for other things as well. It contains tons of info on C++ coding style and C++ in general. If interested, his site is at http://home.satx.rr.com/rdevore/sac/
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.
It's all very well in practice, but it will never work in theory.
I write server code that will be run by another part of the organisation, on machines that I don't have access to. As a result it's useful to be able to turn on extremely detailed tracing so that the guys running the service can send us traces of sessions that didn't behave right.
/* comment */ next to the trace line would be redundant.
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.
Some advice.
Use meaningful variable names:
like:
string iFileName;
(Short of input file name)
Comment your functions:
For example put a header before all your functions that says what the function returns, its purpose and any arguments.
Don't explain how the code works in a comment but, what it does.
An example of a funtion header:
//inputFile Function
//Arguments:
//
//string aFileName
//ifstream iFile
//
//Returns: bool
//
//Description:
//
//The function inputFile takes a string as an
//argument and an ifstream. The ifstream is
//passed by reference and will contain the file
//data once opened. Returns true if the file
//was opened.
Note: Use fewer 'junk' characters huh? Stupid submit form (especially with this subject).
Certainly the most important comments are those that say WHY something
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.
commenting code is bad, it ruins the beauty of a project. The need for commenting comes from bad design, carless metaphors, etc.. good source code needs no comments as 'code should show itself'
ok, yeah.. a bit extreme, but i like to think this way.
what a bunch of nerdy whiners.
I have become somewhat a Code Dictator to me fellow workers because I strongly encourages them to write Beautiful Code (they will call it mobbing, though... ;-) nevermind).
What I mean by this is the usual:
- Clear names for all variables, functions, procedures (etc), commented if necessary
- Comments, comments, comments
- Avoid Spaghetti Code (tm)
- Avoid recursive programming (the code maintainers will thank you)
- Avoid fancy loops with stop criteria based on dubious flags
The rule of thumb is: "Do not comment everything, you co-workers are not stupid. Comment that much that you, after not having worked with the code for at least a year, can at the second glance understand what it does and how you can modify it."
This of course is hard for a beginner, but the more practice you get, the better you become. The key is to not just dropping in comments there and there, but to consistantly and consequently document your code.
Excellence: Moderate (mostly affected by comments on your karma)
int main (int argc, char argv[][]) {
int j;
int i = 7;
char *h = argv[1];
for (j = 0; j < i; ++j) {
q[j] = malloc( sizeof( foo_t ));
}
memcpy( p, &((*((x+i)+k[i->e]).sin_addr),
sizeof(&((*((x+i)+k[i->e]).sin_addr)));
return 0;
}
STOP ME BEFORE I POST AGAIN!
The Pragmatic Programmer - by Andrew Hunt & Davis Thomas
Here's the rules I use:
If you were blocking sigs, you wouldn't have to read this.
If a support developer doesn't know what a little used third party function does and I don't comment it, who loses? Short answer: everyone. Support development team loses, I lose, QA and/or tech support loses as they wait for a fix.
Now, what if I (like so many other programmers and yourself apparently) have my head firmly up my ass so I think all my code is obvious in function and I only need to explain my intent? Well, after being humbled a few times, I'll figure out that it is more useful for everyone if I just use lots of comments, even things that may seem obvious once written, the role of support is vastly improved and my need to help with support is greatly reduced.
Of course, maybe you like doing support programming, it takes all kinds I guess.
I would say that this is part of the problem with code that you might create - you're hiding the implementation section.
The best way to produce the code is to create a clear division between functional elements, a clear division of data elements, and a clear division of implementation and error checking. What I mean by "division" is very dependent upon the language. If you've got an OO language its clearly easier to define the difference between data types using objects than it is in a weakly typed functional language.
However, all of these things can be done with any language. If error checking is taking a lot of space, put it in a separate function, or at the very least put some sort of divider that makes it obvious where the code begins and the debug stuff ends.
The best comment is often well structured code. Comments only make it easier to understand those rare algorithms that can be explained in a non-algorithmic way. (Actually these aren't extremely rare. FFT comes to mind.)
Mod me down and I will become more powerful than you can possibly imagine!
Didn't you mean:
REM Since you are slow, you failed. Commit Hari-kari
...?
STOP ME BEFORE I POST AGAIN!
A couple years ago, I took a programming class at a local community college. The whole class got failing grades for the first few assignments, even though the program did what it was supposed to do and had 4 lines of comments per routine.
Turns out no one got any higher than a C until they made a whole page of comments for each line of code. On top of that, the teacher demanded the code be printed out.... I remember that I ended up turning in a 100 page document once, whereas the program was only about 90 lines.
I think that's a little too much commenting, but he still said more comments needed to be made. I understand where he was coming from (he used to program in Cobol, and this was in 1998, when everyone was scrambling for patching uncommented Y2K code), but there's such a thing as overcommenting.
code should be self explanatory. the variable names should dictat what you are doing, and also, the way the code is broken up is also important. Use comments sparingly, for example a nice one liner (terse but not cryptic) in front of very 5-10 lines block that does ONE(1) thing.
another good time/place to put comments is things that you had a lot of trouble understand (like a description of a complex algorithm). in this specific case (algorithms) it is often useful to include a reference to the place you got the algorithm. oftentimes, if you link to a website (even if it is NOT there when others look at it) at least if it IS there, a good explanation exists (at least better than the one you hopefully gave).
finally, put LONG explanatory comments in front of bugs that took you FOREVER to debug. by this i dont mean put a comment where you accidentally typed x instead of y! if there was an algorithmic problem, IOW a problem with your logic somewhere, and it took a while to figure out the RIGHT way to do it, the person reading it is probably going to have just as hard a time understanding what is there.
QED
BSD is for people who love UNIX. Linux is for those who hate Microsoft.
First off: never underestimate the value of putting research notes in your comments! A simple "This averages O(NlogN), but is worse if the data is presorted" can really make somebody's day.
Now, the long rambling description of how I like to see comments:
Every file should have, right after the boilerplate (after copyright, before #includes etc) a brief description of that file.
Name your functions something concise, and accurate, but not necessarily precise. You don't need sort-sequence-on-predicate when sort will do just as nicely.
The same goes for variables. Using i and j for numeric iterators is fine, but you rarely should use foo and bar. Most variables should also have a short (usually <20 char) comment, although globals should have a longer comment, possibly describing how they're used.
Every function should have a docstring. In some languages, such as C, this is normally comments at the beginning of the function. In some, such as Lisp, there are conventions for including the docstring in a manner that the compiler will recognize.
The first line of the docstring should be a self-contained sentence that tells what the function does. The rest can go into detail about how to call it. The purpose of this bit is "what does a caller of this function need to know". Wait on the implementation notes for now... we want the caller information to be all one, tidy package.
If your language does have docstring support (either directly or through an external tool), then implementation notes belong in comments, not the docstring. Either way, put them after the caller information, so that somebody who just wants to use your function doesn't need to read them.
As an extention of this idea, functions should begin with a brief overview of how they work. (For extremely simple functions, this may be omitted.) If the function implements a formal algorithm, such as a sort or hash algorithm, then a formal description is certainly not out of place, or give a reference. This is also a good place to note any behavorial characteristics.
Divide your code into "paragraphs", between 5 and 20 lines long. Skip a blank line between paragraphs. This also helps find areas that are good candidates for factoring out into separate functions.
Each paragraph may start with a block comment describing either what that paragraph does, or at least the program's state at that point in execution. Feel free to make these as descriptive as you like; they're the landmarks for somebody reading the code.
Loop guards frequently should have a one-line comment describing what they're testing for, in terms of the algorithm as a whole.
If a line's meaning isn't immediately clear, then clarify it with a one-liner.
Any one-liners may be expanded to multi-liners if you need to:
Mark areas that need investigation or more work with a comment of "FIXME"; that makes grepping later on much easier.
You can also use XXX for a similar purpose, or (what I do) to mark areas of grave significance.
Don't worry about descriptive comments being too verbose. Descriptions of program state, why something exists, research notes, or prose all have their place in comments. The only time I've read a file and thought "Gee, this is overcommented" was when it had template comments with changelogs and argument lists.
Now what do you not use comments for?
Don't keep a changelog in your code. Your source-control system does a much better job.
Don't repeat the argument list. The argument list itself does a perfectly fine job of that, and will always be up-to-date. If the purpose of each argument isn't clear by its name, then add a one-line comment to the arguments. (Note: In Perl, don't shift the arguments off as needed. Get all the arguments off in the first line of code if possible, such as my ($self,$filename,$options) = @_; in order to let somebody calling the function to have an argument list available!)
Don't document the language (eg, explaining ++). This not only is unhelpful, but distracts from useful comments. If somebody doesn't know what ++ does, they can look it up.
Credits: Examples snipped and adapted from my own development, as well as CMUCL and FreeBSD sources.
... should be hard to read! HEE! :-)
Artificial intelligence is no match for natural stupidity.
This question is as complex as "How to I write a good book?". As with English, there are many books that will help you with style and mechanics, but helping the reader understand is up to the coder. For example, The Pragmatic Programmer and Code Complete are analogs to Elements of Style and the Dictionary of Modern American Usage.
... is the only truly well-commented code. Literate programming was invented by Knuth. If you don't know who Knuth is: he's the author of the definitive CS work called "The Art of Computer Programming". Ask any of your friends who actually studied computer science about it.
Knuth wrote more than books. For example, he wrote the typesetting program, TeX which is to this very day the most popular way academics in the CS field employ to write their papers (especially using a macro package called LaTex). He just wasn't satisfied with the available ways to write mathematical books at the time (early 80s). He had a good reason - you can see the difference in quality between it and anything else - especially Word (Ugh).
To ensure you'll have the right idea about the quality of his work, note he's actually sending people checks when they find a bug in his books or his code. Of course people tend to frame them rather than cache them :-). Also note that nobody has managed to obtain such a check for a long time.
So, what is literate programming anyway? Instead of inventing yet another definition, here's a pretty good definition which you can find in the site, together with many others:
Marc van Leeuwen. "Requirements for Literate Programming" in CWEBx Manual, pg. 3-4.
The basic idea of literate programming is to take a fundamentally different starting point for the presentation of programs to human readers, without any direct effect on the program as seen by the computer. Rather than to present the program in the form in which it will be compiled (or executed), and to intercalate comments to help humans understand what is going on (and which the compiler will kindly ignore), the presentation focuses on explaining to humans the design and construction of the program, while pieces of actual program code are inserted to make the description precise and to tell the computer what it should do. The program description should describe parts of the algorithm as they occur in the design process, rather than in the completed program text. For reasons of maintainability it is essential however that the program description defines the actual program text; if this were defined in a separate source document, then inconsistencies would be almost impossible to prevent. If programs are written in a way that concentrates on explaining their design to human readers, then they can be considered as works of (technical) literature; it is for this reason that Knuth has named this style of software construction and description "literate programming".
Does it work in practice? All I can say is that I have used it in a real-world project with great success. The main downsides to it, and this applies to any type of documentation, is that it takes up-front time (even if it does save time later), and that you need to employ people with some measure of writing ability. It is surprising how many people can code well, but are hard-pressed to write coherent, readable description of their code. Especially if you write your documentation in English and the programmer's native language is Hebrew or Russian :-(
Oh, and it also is hard to do in IDEs like Visual Studio. And you won't learn about it in your university, never mind your VB in 3 days course. Just like design by contract and many other techniques, the problem isn't that humanity doesn't know how to write software well - it is that humanity doesn't want to.
If you have too much comments it can be difficult to read the source code.
The most important thing is to comment code that is not obvious (i.e. code the compensates for a bug in the OS, or code that has been produced by trial and error)
It's better to have logically structured code and logically named variables and function names, rather than reams of comments, trying to make up for the above.
Remember that comments aren't a subsitution for code documentation
And always put the comments in at the last stage (after everyting is implemented and debugged).
After someone reads my code they often feel an unresistable urge to kill me.
It's hard to become a programmer when you spend most of your time dodgeing bullets.
comment? what's a comment?
This message was brought to you by the death of 30 brain cells.
i have some standard names for my var like "$bla" and "$affe" that i define every time i write new code and i use vars like "$v0-$v99" but i always write comments under them to see what it is and when it's finished i usually rename them to something like "$HeaderVertPos" or stuff to make it easier to read. for me the main issue aint the missing comments but cryptic var names name and stupid and rendundant placed but heavily used backup-vars that you wont figure out...
The biggest problem I have with going through code (as a contractor, I tend to read a lot of new "to me" code) is the case where you're dealing with 2nd or third generation code, the original developers are long gone, and the intent of the routines has changed but the header/interface comments have not. One has to read and understand the code in order to make the changes and while the comments might be helpful, they also might be outdated and wrong. Too many times I've found a comment beside a routine call that say one thing and when I go into the routine, find it's something totally different. I am especially careful about comments that talk about expected return values or side effects. These generally aren't a problem on release 1.0 code but there's a lot of jobs out there dealing with release 5 versions of things where the comments might not have kept pace with the product.
Many times a group is unwilling to submit comment/non-code changes for a module (due to the return values changing say) to source control because they don't want to have so many modules change for what they see as a "trivial" fix in another module. It's tough to get some of those changes through many review procedures and this is what causes comments in "callers" code to be outdated. Use the comments as a guide, not as gospel.
I find ccdoc to be a great help. It's a JavaDoc like tool for C++.
call it complex_multi_word_variable, not ComplexMultiWordVariable, for readability's sake. ????
//Complex Multi word. Does...
How is a 4 word variable readable?
Imagine reading code with > 100 variables like that! Worse than reading a bad novel.
Both forms are unreadable!
Too add insult to injury most coders like this go on to write long redundant comments. Essentially repeating what the long variable name tells you!!
Ever wondered why Mathew is Mat, Catherine is Cathy, Timothy is Tim, Telephony is phony or why a lot of people ask for middle initial instead of the full middle name?
Instead try something like
cWordVar or sWord_Var
Always keep var names to ideally 2 words
Anything longer is worse than x, y, z.
Both extremes are bad!!
My favorite example of well commented code, to the extreme, was a text editor w/ assembly code published in a Byte mag about 1983 or so (VDO Video Display Oriented). The source listing was nicely broken down into functions with a paragraph explaining exactely what was going on and why for maybe every 2 or 3 instructions! Anyway, the amount of English text far outweighed the actual code by maybe 10 to 1.
try { do() || do_not(); } catch (JediException err) { yoda(err); }
On a running web site ecommerce web site...
$creditcard = getParameter("credit-card-value");
# TODO: Validate credit card number...
well, it shows me as the oldest when sorting oldest first... 10 PRINT "Booya Grandma" REM Comments in BASIC are begun with REM not //
REM Mr. FAKE Linus
20 GOTO 10
I remember one inspired indevidual saying
Good code doesn't need commenting and bad code doesn't deserve commenting
I tend to stick to
//Get your filthy hands off my code, you'll be sorry
or
' Ha choke on this script jockey
forgot the BRs... corrected below<br><br>
//<br>REM Mr. FAKE Linus 20 GOTO 10<br>RUN
well, it shows me as the oldest when sorting oldest first...<br><br>10 PRINT "Booya Grandma"<br>REM Comments in BASIC are begun with REM not
I'm currently developing a project where I have to modify existing source code developed by someone else. I spend most of the time trying to figure out WHY the previous programmer did something the way he did it, and what the hell he was thinking. Write these into your comments. Also, write down in comments small tips for the programmers that might come after you. Comments in the style of:
/* This function expects an object that has been fully filled and checked for errors before. Be sure to never send it a NULL one! */
/* We're invoking the call to the database with the "mode" flag set to zero because currently it won't use it - but it COULD be used in the future. */
or
help a lot.
I also have to modify Java source, where I have generic classes that inherit from previous ones a lot of attributes. For example:
public class A {
public String s;
public double d;
public long l;
}
and
public class B extends A {
public String ss;
}
I prefer to write class B like this:
public class B extends A {
// public String s; : A
// public double d; : A
// public long l; : A
public String ss;
}
That way I can see quickly all of the attributes class B contains.
"Trust me - I know what I'm doing."
- Sledge Hammer
In any situation where I see the need for code commentary, I try first to find a way to make the code clearer. If the source code is sufficiently clear, comments are unnecessary. This also avoids the risk that the comments will diverge from the code - making claims that were once true, but no longer reflect the code's actual logic.
// empty or null uiInitializerClassName means this task is not
// defined for use in this interface. Skip it.
... do something ...
... do something ...
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.
Stop-Prism.org: Opt Out of Surveillance
Sun has some good advice about this on their website. They talk about using method level documentation as an API contract specification, as a programming guide, or both. A lot of that paper is written with the JavaDoc tool in mind, but the general points are valid for any language (and you can always use Doxygen, if you want to apply the specifics to C++).
Lets be honest here. Using comments as a crutch to prevent you from having to figure out what what the program does is destined to fail.
Comments are not compiled. They do not affect the outcome of the program. If you want to know what the code does, even in the presence of comments, you have to look at the code. Comments can be out of date, misleading, and just plain wrong.
There is no substitute for just reading the code, and learning to understand what it means.
Even in a beautifully commented piece of code, you will still have to go back to the code, to confirm what its doing.
Just try to remember. Comments arent compiled. They are not the code. If you want to know what the code does, you have to read the damned code.
That being said, the comments that are most likely to have an impact on others is comments not about the code, but about intentions. Its pretty easy to convert your intentions in to code, but alot harder to convert your code back in to what you were trying to do.
The code tells me what you did, but not why. And comments that talk about why you are doing something, and why you chose this path, are less likely to be wrong, missleading, or out of sync.
If you know what you are doing, you can look at uncommented code and figure out what its doing, but not why. Why is whats important.
Coding is a kind of compression. It takes the verbose ideas that you and your team have been tossing around for a while, and convertes them in to something quite sparse for the compiler. If I look at your code, I might be able to reconstruct your ideas and intentions, but its not likely. Thats what I need added to the code.
-
Another good thing we started with was adding notaion of in-, out- and in-and-out parameters, to separate them from auto's and globals.
Parameters that are in (readonly) always start with i, parameters that are pointers to uninitialized buffers that are initialized by the funcion starts with o, parameters that point to initialized buffers that are modified starts with io, all variables defined in a function starts with t (yes, could be confused with types, we really should have selected another letter instead), and all attributes starts with m.
This way, we never accidently create bugs by accessing a local instead of a parameter or a global or static variable, or an attribute, which we found was a Good Thing(tm). Also, the parameter list became more self-describing.
Who the fuck cares if it looks pretty when you have to spend 2 useless hours lining up a bunch of *****'s just because some moron thought that would be the best way to comment.
Here is an example, the first line of /'s where taken out to get past the lameness filter...
int bar::getFoo() {
return foo;
}
Gee...I wonder why I enjoyed programming until I went to college...
Any sufficiently advanced influence is indistinguishable from control.
In some VB code I saw:
' Add one to the counter variable.
intCounter = intCounter + 1
No kidding. Every line was commented that way. I didn't know whether to laugh or cry.
My favourite book on code readability happens
to be free. Unfortunately it is not about
C++.
Try:
Ada95 quality and style
The most useful thing to document in code comments is the intended behaviour of the code. With this information it is simple for any half-decent hacker to find out if the code does what it is supposed to do.
Takes the guesswork out of debugging. If the code doesn't do what the comments say it was intended to do then you know you've found a bug.
-- Rich
I had a documentation post, but it got nerfed by slashdotomatics lameness filter.
2 parts to documentation
#1 Use a bunch of - to make a line really long
//---
Section off your code. And comment what it does.
#2 Document important variables that are well used, especially globals
God spoke to me
Write clear concise code that documents itself. Use well named methods/functions/procedures/subroutines that do one small thing. IOW, write blindingly obvious code that doesn't need comments. Use comments to explain difficult or clever code, and then consider the comment as a red flag - maybe that clever code shouldn't be so clever. Maybe it's a time-critical algorithm, and it DOES need to be that difficult. That's why they pay us the big bucks.
All that being said, I really like javadoc and it's c# bastard cousin. But that's a different story. Comments have a tendency to rot, but the code is ALWAYS the most accurate "comment" about what the code does.
meh.
In any CS curriculum you would have learned proper code documentation standards. Go take a Software Engineering course.
Of course, if you stick to these guidelines, you're not writing comments, but patents.. So better hide those from your coworkers, otherwise they'll try to claim royalties..
SCO employee? Check out the bounty
- Persistent and temporary file formats
- User interface
- Network protocols
- System and architectural design
- Relationships between data elements (or objects if you think that way)
Some of the above are addressed by UML and associated tools, but for things like network protocols the RFC-type format is the hands-down winner. A particular implementation of a good idea in code might last a couple of years, but the protocols for a truly revolutionary idea will live for decades. (Look at Mosaic and HTTP/HTML for a good recent example.)IMHO, comments are often confusing. A source code that has plenty of comments becomes unreadable. And comments aren't always in sync with the code when changes are made.
:
:
A source code with no comment, but whoose structure is very simple is way easier to understand. When the compiler sees long and overcomplicated expressions, it painfully transforms them into more, but basic expressions. So why not write simple code?
I often see complicated lines with plenty of ternary operator usage. Why? Write the same code with simple 'if' statements. The generated code will be exactly the same, but the source code will be easy to understand.
Another very confusing thing (IMHO) is the usage of expressions without explicit braces in loops and conditional statements. Ie. things like
if (ready())
while (*++take)
if (*take == 4)
foo();
Without indentation, it's very confusing. Worse : what if I want to add an 'else' here? If I want to add an 'else' to the second if, I really have to properly indent it to avoid confusion. If I want to add an 'else' to the first if, I have to add braces. This sort of thing doesn't ease the usage of macros and can give very nasty bugs when cutting/pasting blocks without carefully understanding where implicit braces are. So why not simply write
if (ready() != 0) {
while (*++take != 0) {
if (*take == 4) {
foo();
}
}
}
The generated code will be exacly the same, but there's no possible confusion here.
Also, 'goto' is not bad. Really. When you have to break from several loops, or just to avoid deep nesting of statements, a well placed 'goto end' is way clearer and faster than useless functions and silly 'flag_to_see_if_we_have_to_exit' variables. Don't forget that after compilation, any program will have 70% of goto-like assembler opcodes.
Comments can be interesting to note bugs, or TODO stuff.
Also have a look at the style(9) adopted by the OpenBSD team. There are good ideas.
{{.sig}}
There is no easier way to make code ugly and unreadable than to use hungarian notiation. nCount is not in anyway more readable that cnt, it clutters the code and is very annoying. If your code really needs to encode the data type in the variable name then there is something horribly wrong with it.
The difference between Canada and the USA is that in Canada healthcare is a right and gun ownership is a privilege.
Sure, some of your stuffy cow-orkers may challenge this practice, but it's all for a good cause.
Imagine reading code with > 100 variables like that! Worse than reading a bad novel.
//Complex Multi word. Does...
but at least it's readable!
Ever wondered why Mathew is Mat, Catherine is Cathy, Timothy is Tim, Telephony is phony or why a lot of people ask for middle initial instead of the full middle name?
no
Instead try something like
cWordVar or sWord_Var
Yeah that's descriptive! Now I pity the poor bastard who has to maintain this code.
Also, what's up with this hungarian bullshit? You wanna know the type of a variable then see its declaration.
Variable names should be descriptive. If more than 2 words are required to get across a description then so be it. At least it will be more likely to be understood by the next person.
If you define structure with public stuff but default, why the hell are you using 'class'? Use 'struct'. The only difference between 'class' and 'struct' is that 'class' has private members by default, while 'struct' has them public by default.
{{.sig}}
comment the function before coding it!
Why?
1) You will have a better clue of what is it that the function should do. Help you find any problem or hole you got in your approach.
2) It will be clearer for other who read the source code later.
By and large, comments for "tricky" code, complex algorithms, or non-obvious functionality are all you need to make sure anyone can figure out what is going on in the code.
The one exception I make to this is to make sure every class and method is JavaDoc'ed extensively. This helps those people USING the class as much as it helps those who are maintaining/modifying the class. I find that overall it increases the quality of code and reduces bugs significantly.
I cannot say enough good things about Doxygen.
I work with huge source trees written in C,C++ and Java, and with Doxygen you can use identical (or not) commenting styles and then let doxygen present the documentation in a nice way. I can automagically create html, man pages, LaTex, pdf, rtf and/or xml documents from mixtures of source code.... entirely flexible and configurable.
Power and ease of use aside, the real value I get from Doxygen is it's dual sided purpose: It can be used as a tool for development or as a straight public documentation generator. I can take a single source tree and at once generate a super hyperlinked code searcher and a high-level functional description document for non-coders (say your boss). It allows a developer to visually see the architecture of the system through graphical class hierarchies and then hyperlink *directly* to the source code that generated it. Far and away more mature than java-docs....
You get to the point of wanting to comment more, because the output that Doxygen generates based on your source code comments is so usefull and readable.
Get it, use it... it will make working on small parts of a large system easier.
---------- slow blades penetrate ----------
How do we deal with the problem of tons of existing code without comments? Adding comments to it when it is hard to determine the intended functionality of said code seems like it would be harder than rewriting the code and adding comments to the new code.
stuff |
When I was an intern at a graphics company, I found myself wishing for data documentation a lot more than code documentation. You can generally figure out what a piece of code is doing by following it, once you know how to interpret the variables it is working on.
For example, a variable called, say, pDrawSurface is all very nice: it tells you that it is a pointer to the surface you're drawing on. But what format is it in? If it's a NULL pointer, what does it mean? If you have a front buffer and a back buffer, which is it? What if you're rendering to a texture instead of a screen surface? My point is that while good variable names are definitely a requirement, they are often insufficient to _completely_ define what a variable does.
My feeling is that a variable should have a reasonably descriptive name that will help you remember what it does, but the more obscure points should be documented at the point where the variable is defined. Of course this can also apply to functions, types, parameters etc.
CDC 6000 assembler program whose only comment read:
I get peeved at how many people leave out this critical information. Lets say they have a small section of code that is changing information in a database on the fly as it is displayed to a client. They will comment that the code changes the value but nothing else. Oh how I cringe. Not to mention people who don't comment changes they made.
What I usually really wish for when I read someone elses code is this: I would like a paragraph or two at the beginning giving an overview. This overview should first describe why this code exists - what problem it is meant to solve - how it fits into the general scheme of things. Secondly, it should explain in general terms how it works.
As to the details of how it works - well, as they say well written code should be self explanatory, so I don't think this is so necessary. But well written code can never replace the overview.
The best commented code is the code that is commented on 'By Others',
When they ask who what the hells going on, you should be writing clearer code.
When they tell you 'This ways better', you should listen.
When they tell you 'Theres a buffer overrun' you can fix it.
When they tell you 'Theres a back door left in IE version 5 that allows Bill G to own your soul' you should use open source software.
thank God the internet isn't a human right.
(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...)
Any particular reason you didn't use Rose, that you want to share? I am just getting aquianted with Rose now, and I am pretty enthusiastic.
-Kraft
Live and let live
Comment are useful to describe why. Why this is needed, why you did it this way. The code itself, assuming you've choosen good descriptive names describes what you did. You cannot indicate the why in the code itself. Also I feel writing comments, and code for that matter, should be addressed to the next person to look at the code. And the next person isn't as sharp as you!
A true Kingon does not comment his code.
1. What the code is supposed to do
2. Why it is doing it the way it is (to save yourself the "why didn't you..."s)
3. Update the comments when you update the code!!!
4. If it has a high comment / code ratio then something is wrong
At one job I laboriously commented the Y2K bugs as we went along in advance of our Y2K testing. One programmers job was to remove my comments - not fix the bugs, just remove the comments.
What the client doesn't see the client doesn't know.
/* This was hard to write, it should be hard to understand */
M@
Krispy Cream is people
Comment answer the "why" question.
The code answers the "how" question.
External documentation answer "what", "who" and "when".
Parameters and returns of functions must also be documented, especially when they are not obvious or have side effects.
Occasionally I have been reading some code and the idiot put in a comment that just gave the whole thing away.
Never comment each function, just put one big comment at the end of the file.
Or better yet: have a seperate file that contains all your projects code comments so that they are easily found in one convenient place.
Use acronyms and abbreviations to reduce source code size.
I can't stress this enough, make up your own acronyms and abbreviations if you have to, brevity is the key.
Hope this helps.
So much to do, so little bandwidth.
--
Try Mozilla
First of all, keep your comments confined mostly to your header files. That is,
This is very bad. The comment above Foo::bar belongs in foo.h, not foo.cc. I should never have to read your .cc/.cpp/.cp files in order to use them. The comments in foo.cc should only explain clever tricks, workarounds, etc. There are two purposes for comments: (1) defining interfaces to reuse some code later and (2) describing unusual or unexpected ways of doing things. (1) belongs only in header files. (2) belongs mostly in .cc files, but can also go in headers if there's something particularly nasty afoot. This makes it easy to look at a particular project and get a good idea of how things interact, without worrying about details.
I work more with C than with C++, but the exact same rule applies (which is not always true - there is no such language as "C/C++" and what is idiomatic for one is completely awkward in the other). Modern idiomatic C dictates that you separate your code into "modules" with a .h and a .c file for each "module." .c files should only be found alone if they don't export any functions that are used in another .c file (eg, they only "use" modules rather than implement anything). The distinction should be made explicit by declaring module-local functions as 'static'
Another thing I find quite useful is using the "MVC" paradigm (Model, View, Controller). A concrete example: any web-based database application, like slashdot, for instance. The "Model" part is the actual database schemas. The "Interface" part generates HTML. The "Controller" part is the only part that actually constructs any SQL statements. Your controller has good APIs if you can completely change your database schemas without changing any code in the "Interface" part. Generally, well-designed systems like this require comments to define the "Controller" APIs, and don't have too many comments elsewhere.
Someone else has already mentioned The Practice of Programming and I'd like to chime in that this is an excellent book.
Look - if it wasn't for poorly commented code, I wouldn't be able to code at all today. Sifting through junk code allowed me to learn more about programming (good and bad) than any book or class.
...except for FIXME!
Accept Eris as your Fnord and personally sate her
Writing good comments can be accomplished by applying one very simple rule:
-> Write the comments before you write the code.
If your writing a sorting function, take the 5 minutes required and write the comments for what your going to do before you do it. You'll be amazed what a difference such a simple step can make. Plus, you'll see the holes in your logic form quickly if there are any.
Also when making changes to existing code, the same simple rule applies. Write out all of your code changes in the comments first. Then implement the changes. The same benefits apply in this case as in when writing new code. But there is an additional, very important benefit in this case: comments in code are kept up to date. How many times have you seen source code that has _incorrect_ comments? Plenty I'm sure - and in most cases that happens because someone fixes a problem or change logic without updating the comments. Very bad. So, by commenting first when working with existing code, you solve this problem as well.
Take care,
Brian
--
--
http://www.assortedinternet.com/hosting/
.:: Strunk And White-Em-C ::.
ehehehe
I don't actually keep to the style of capitalizing the first letter of functions and not capitalizing variables, or vice-a-versa. Sometimes I swap these.
But I do keep constants in all caps.
More importantly, I keep the spacing standardized, and the braces in the same place all the time, except for one line routines. (rare)
void OpenFile (cha r* filename)
{
...
}
On the other hand, I get descriptive with comments. I usually write out what I am attempting to do with the program in pseudo code before I start coding, and then keep that in the code where appropriate: The program description at the top with the calls it makes; The pseudo code for the methods are kept with the methods.
Even more so, I try to describe variables where necessary. It's usually not necessary to describe things like idx while in a method, but parameters and other variables usually are good bets for comments. Even a variable like MaxRecordSize can use a comment, since it might not be clear if it means the maximum size possible, or the maximum size found.
I also do almost exclusive perl. And I have to deal with several legacy web apps that are failry complicated. I totally agree with commenting logical blocks of code. And I have a few other places that are useful for reverse-engineers...
- If you have a fairly long subroutine, it helps the reader to comment the begninning AND the END of the block. Something like:
# Comment briefly describing the upcoming block of code
sub this_thing {
lengthy bit of code
} # End of this_thing
And how about this:
- Say you build a group of files where an executable chunk requires several other files. When you use a variable that is established/initialized in the "required" file, drop in a comment to tell the reader where the hell you got it from. It is extremely frustrating to see variables magically appear in a file, and then have to back-track a variable through 20 other files to figure out what you're doing with the value.
Is quite the contrary - most programmers think to _much_ before they code, thinking about possible future extensions before making code that solves the current problems. Check out extreme programming (with it's motto 'Do the simplest thing that could possibly work') for more arguments in this vein.
I can recall a group of managers reviewing my code and one of the comments I got back was "too many comments"
:)
not sure what they were getting at. but in their honor I now make an effort to write more unreadable code and I never comment anything.
job security
There are some odd things afoot now, in the Villa Straylight.
The original poster said he was programming Java, and in Java you've not got 'struct' like you have in C/C++ -- so you're stuck with using 'class' for everything.
hth clarify things somewhat.You know that your code is well-commented when the moderators give it a +5 Informative.
Symbol names are generally a better place to put in comments than explicit comments. They are less likely to suffer bitrot and produce more readable code that almost looks like executable pseudo code.
// Not optimal
// Get next customer array index
For example (In a full-width program screen, one-line functions would only take a single line, so the code bloat here is an illusion),
---
i++;
// Spam customer
mail(customers[i]->email_address, mtext);
// Lose customer
delete customers[i];
---
// No comments, but better
inline customer_t *
next_customer(customer_t *currentCustomer)
{
return ++currentCustomer;
}
void
spam_customer(customer_t *customer)
{
mail(currentCustomer->email_address,
exciting_offer);
}
void lose_customer(customer_t *customer)
{
delete customer;
}
customer = nextCustomer(customer);
spam_customer(customer);
lose_customer(customer);
----
Note that inline functions can always be used to create new function names without overhead.
IMO, the most useful and frequently overlooked element in documenting code is:
Meaningful variable/function/method/class names!
So many developers are satisfied with instance names like the ubiquitous "temp" rather than more meaningful ones like "jobStagingList".
Well-chosen and expressive variable names go a long way towards making code self-documenting.
The only thing that we learn from history is that nobody learns anything from history.
I believe peer pressure is the most effective way to improve code readability within a programming team. Coding standards can only address low-level issues, and only if they are enforced. Regular peer review focuses everyone's attention on true readability issues. A senior programmer can learn a lot from a junior programmer this way.
I've seen several links so far to the excellent Code Complete, and I second that one wholeheartedly. One commenting scheme that they suggest is writing your code first in pseudocode, just to get the logic down in plain English (or plain language of your choice), with indentations to indicate logic:
// Construct email from user input .= $form['emailSenderName']." says to tell you hello!";
// Send email to address indicatedc t'],$body);
// If no:
// Send form back to user
// Highlight email field
// Show email validation message
// increment i
Get email form data from client input
Is email address valid?
If yes:
Construct email from user input
Send email to address indicated
If no:
Send form back to user
Highlight email field
Show email validation message
Once you're happy with the pseudocode (which, for me, more often than not clears up at least a little shaky logic for me before coding even begins), you can add your code to the pseudocode line by line, turning the pseudo-stuff into your comments. Combined with smart variable names, this is usually all you need. Sorry the example's in PHP:
// Get email form data from client input
$form = getFormInput($thisClient);
// Is email address valid?
if (validateEmail($form['emailTo'])) {
$body = "Hi ".$form['emailReceiverName'].".";
$body
mail ($form['emailTo'],$form['emailFrom'],$form['subje
}
else {
sendForm("email", "That's not a vaild email address!");
}
OK, this is a pretty weak piece of code (I haven't had any coffee yet), but the point is that the pseudocode comments plus good variable/function names tend to be a real good
start on your comments, almost self-documenting. And it tends to produce comments that straddle that line between too much information and not enough. Because the pseudocode shouldn't deal with the nuts'n'bolts of the programming language, you'll never write comments like the hated
i++;
although one of my Golden Rules of Technical Communication is "too much information is always better than not enough".
"Luck is the residue of design" --Branch Rickey
Now I'm not saying that all programmers who use HN are idiots. This is just in my experience, which is a relatively small cross section of a much greater pool of code. Seeing the style does set an expectation with me now, though, since all my experiences thus far have been bad. Perhaps one day I'll be pleasantly surprised.
Hmm... asking about opinions on HN might make a good interview question (on either side of the table) now that I think about it. I'll have to add that to my list of questions for when they ask "Do you have any questions?"
I'm trying to teach myself to set people on fire with my mind... Is it hot in here?
At one stage I had to do a quick and dirty with some software that was hitting priority inversion problems. I was working AC who had caused the issue by sloppy coding - I commented the fix with a warning that this was a "Kludge" and needed a proper cleanup later. AC petitioned for and got the "Kludge" word removed.
See my journal, I write things there
First of all, I name all my variables mnemonically, like workerFirstName, and describe them in a comment when I declare them. Then, if I am building an array from a database query, I lay out a description for each element of the array somewhere where it can't be missed like at the top of the program or the beginning of the subroutine where it's assembled.
At the top of each subroutine I write, I include a short paragraph describing in plain english what the basic idea of the subroutine is, along with a short writeup of any weird things that aren't obvious, like maybe a pass-by-reference variable that is altered as a side effect (although I don't do that much, occasionally it does come up).
I also like to break my code up into easily explainable chunks and add a short explanation of what's going on in between each chunk. For example, maybe one chunk would be a section that queries a database to see if there are any records for a particular client. If there are, we may exit the subroutine and if there aren't, we may proceed with an insert. Well, I would describe that chunk with a little blurb. If the chunk gets big enough to get its own subroutine, the blurb would describe why I'm using that particular function call. And so on.
The important thing is, for each actual *task* in your program (a task being defined in my view as a single step like a database query or a test on some fetched data), there should be some kind of explanation of the task so that six months from now, when you're maintaining the code, you'll be able to remember what you did and why. This will save you SO much time and trouble down the road, it's not even funny.
Another helpful thing: add a variable to the top of your program, called "amIDebugging". Set it to "TRUE" if you're still testing and "FALSE" once you're done. Set up your program so that if amIDebugging is equal to "TRUE", you open up an output file for logging, and in your code, whenever you have something you want to log for debugging purposes, output a comment or two, inside an if statement that tests this variable. This is cool, isn't it? As soon as you're done debugging, set the value to "FALSE" and all your comments and the log file go away. It's a little more helpful than using a debugger, because you can scan through the logfile if only, say, some records are failing. You can compare records that succeeded to records that failed and see patterns... Of course, that's more database oriented, but still.
I just don't see what you're driving at. Your question seems vague -- sort of "I don't understand what's going on sometimes, help?"
I think Slashdot needs some kind of commenting standards for it's postings.
What is needed is a document that bridges this gap. you need to have something that shows how all the parts fit together, and how the data flows through the program. Now while you might have this in your design document, it needs to be referenced back to the code, tell what the real filenames, data types, functions are. Some detailed examples of how the program runs are very helpful.
alright here's my little anecdote about well
:)
commented code.
We grabbed some free code for a little utility
to help with a project at work, with the aim of
pulling out a bunch of the relevant functions and
changing them around a bit. And when i looked at
the code, all the comments were in german
It may well have been amazingly well commented in german, but it didn't help us any.
"Weasling out of work is important to learn; it is what separates humans from animals. Except for weasels."
IIRC, Beagle Bros. commented everything they did on the Apple II, and put a line or two of ****** to set it apart. Was great to find instruction in their BASIC programs, since they were anything but (Basic. AhHA!;P . That's how I learned the ins and outs of the Apple II. That, and playing lots of Rescue Raiders.
Get a book called Code Complete, it is basically a guide to writing good code, using good, solid, standard naming conventions, and proper commenting.
I have two words that come to mind when people see code like yours:
JOB SECURITY
and dont even take that as a compliment. it's childish and extremely detrimental to all progress in whatever company is dumb enough to employ you with such shitty coding technique.
I personally have been a unix sys admin for almost 10 years now and find myself having to write a lot of perl to accomplish things automatically. if my employer feels the need to get rid of me after I have created such a great environment (where others can edit my scripts), that would be an indication to me that I need to train harder and become more skilled.
keeping your job by writing crap that no one can possibly understand only creates hatred from the others who may have to read and alter your code.
bah, I'm done.
A year spent in artificial intelligence is enough to make one believe in God.
Lots of people here are citing code complete. I am also a big fan of this book. In it, McConnell mentions a defense department survey where they found that variable names were most readable when they were in the neighborhood of 10-20 characters. He was mostly campaigning against short names, but long names are also difficult to read (and can be the source of hard-to-find bugs when character 75 should have been capitalized but wasnt).
Writing 20-character names to avoid using a comment makes sense. If avoiding a comment means using an 80-character name, bite the bullet and use the comment.
For advice on commenting, as well as so many other issues that differentiate a journeyman software engineer from a master, I highly recommend The Pragmatic Programmer. When I start a new job, I often wish my coworkers had read it, and by the time I leave the job, I try and make sure that as many as possible have.
All right, I know that sounds like a commercial, but it's really a great book.
Kevin Fox
You're correct about obscure third-party functions, but if you put too many comments explaining functionality (x->run(); /* run x */ i++ /* increment i */), your code will be cluttered to the point of unreadability.
What to avoid? C / C++.
What to do? Switch to Python.
(in all seriousness, Python seems to quietly nudge users into nice behaviour, and its braces-free, consistent indentation - no more arguements about where to put a f'ing brace! - is a joy to read.)
As an example, I suggest you look at the comments for SWISH++. It uses function preambles and cites references to standards and other works.
If you reply, do so only to what I explicitly wrote. If I didn't write it, don't assume or infer it.
At my last (final?) programming job, we had the misfortune of being "led" by people with more business knowledge than computer knowledge and the inability to understand that knowing one thing doesn't necessarily mean you know everything. Thus, in addition to writing comments regarding functionality, I had to start writing comments to cover my butt.
The last thing a programmer wants is for a programming manager to do a difference check on something he has checked in, see the changed code, and then come by asking why he intentionally wrecked the program. Every time we checked a program out, we were required to make a change management comment at the beginning. On one memorable occasion I had to put the finger on one of our managers for ordering me to make some changes that were irresponsible (hard-coded variables, etc) and basically set the stage for us doing some free future programming fixes.
One thing I realized after working a couple of years is that you need to make signposts to help protect your professional reputation. Your face may be forgotten, but people 10 years down the road will know you by the code you have written. Ideally we have the time to completely rewrite bad code so that we can make our own elegant solution, but sometimes you only have 4 hours, and providing a work-around is the only way to do it. Do you want people later on thinking that you're a dumb, lazy bastard? No. If you're in a town with relatively few job oppportunities, you don't want the grapevine to start producing sour fruit with your name on it just because you've been told to do something cheesy, shady, stupid, etc.
Did I get away with putting the manager's name and directive in my comments? Not entirely, but everybody knew afterwards that I wasn't the ignoramus responsible for what I had just done.
Keep it short, stupid. Functions (methods, procedures, whatever you call them) should be as short as reasonably possible. Keep it simple, stupid. Writing lines like that look like sumarian may be cool, but are going to be really hard to maintain. If it takes you longer to explain all the neat tricks you're doing then it does to write the line, you're being too cryptic. Keep it standard, stupid. The overuse of "#define FOO BAR" statements in c is a good example. Likewise, although =+ and += used to mean the same thing, the standard suggests that you use += nowadays. Keep it syntatic, stupid. The days of 6-character variables are long gone. The name of the variable should have some relevance to the use of the variable, such as "MailingAddress[]", not "MA[]". Finally, comments should probably never be used to describe individual program lines. If you need to use something like f03vun( //Verify the city/state.
You should rename your function to
VerifyCityState(
Karma: Food Fight (Mostly affected by Date Plate).
One such case is where no code is written and none should be, but looks like a place where a particular few lines of code should be written. You need a comment to say "Don't do [blarg] because [wibble]". In other words, you should comment the conspicuous absence of code.
Also, even 'obvious' comments, if written well can be a great help when they show the logical steps of a procedure as you're scrolling the page like a microfiche without caring to read the actual code till you find the place you want to work on.
Blancmange
Ahh, yes, another thing Microsoft claims to have "invented", even though we were using conventions like this in assembly language (and other languages whose only data type was the machine word) for decades...
Admittedly sometimes people get carried away when commenting thier code. I would rather read too much than not have anything at all though. Just so long as they are saying something. Disk space is cheap now. Very cheap. It doesn't hurt to explain an algorythm or the data structures being used, even if they are in common use. Rather that than try and figure it out by reading some cryptic optimized code that, while it works, takes you a while to figure it out.
I think the most value a programmer can provide in comments is details as to why certain code was written the way it was.
Comments can certainly help a lot in terms of figuring out what someone's code is trying to do, but you can always figure that part out eventually.
Sometimes the reasons why a programmer chooses to do something or do it a certain way are very important yet impossible to figure out by only reading the non-commented source.
Beagle Bros! *eyes tearing* I remember those halcyon days! So innocent...so much in so little RAM.
It is by the juice of the coffee bean that thoughts acquire speed, the teeth acquire stains. The stains become a warning
Why bother.
The second type is code dispersed throughout, but none at the beginning. This tells you *how* it is doing it, whatever "it" is.
So, I find the best is to use both. For one, at the very beginning of the code say a lot. Basically what the problem is (that required code), what the answer is (the program itself), and the approach to answering it (the style).
With that in mind, any reviewer (including you!) will get the correct mindset when looking at the code.
Then, a second level is needed. That is, the basic idea of what each section of code does. Something like, "this function...", or, "this loop...".
For the third, each line of code gets a comment, on why it is needed. It is not always needed, but the overwhelming majority of lines could use a simple explanation.
I find the second level to be the most important. And the third level to be next. I have many times skipped the first level, because it was blatantly obvious.
As a rule of thumb, there should be more comments than code. If there isn't, you're not commenting properly.
Have you read my journal today?
Also, It does not hurt to be a little selfish when commenting code. Assume you will be the one who reads the comment(s) six months from now. So make it good enough so even you can understand what you did.
I have been involved in software development for almost 20 years, and I have seen some bizarre stuff. I have found the only comments worth the effort answer the question "why".
Cheers.
a well-commented program is a program whose comments, if I saw just them and not the program, I could write the program without needing to think up implementation details, because they'd be all right in front of me. I have a dickens of a time trying to write comments that way though.
Explain WHY the code works as it does, not WHAT it does.
Anybody can tell what it's doing. The reasons behind the design are another matter entirely. Here are some examples.
Just make sure that coders know that their comments are to be factual, not emotional. Comments like "I'm doing it this way because Bob said I had to" are useless at best, and inflammatory at worst.After reading Code Complete, which was great, I found Writing Solid Code a laugh a page for the first fifty pages and then more of a cry.
Writing Solid Code is full of stupid things like:
Code Complete has a nice section on how some coders write their code like love letters to a computer. It's great. Buy one for your dog too.
Blancmange
Code Reviews - We love them, we hate them, but they work WONDERS. To have another programmer read over your code and have to try to figure it out is absolutely invaluable. Besides finding really obvious bugs or questionable places, your commentary can be critiqued as well.
For those of you that program by yourself, do the "let-it-ferment" thing. Write some code, then stick it at the bottom of your stack and pull it out in a week. If the comments and code still make easy reading and good sense, keep it. Otherwise, assume if you can't read it in a week, no one else will be able to read it the first time, either.
In an actual programming dept., if you're the manager/boss, make a set time each week to review code by other members and stick to it. Your programmers may complain but they'll complain worse if they have to be there till 2am fixing a really dumb mistake.
Blog,Twitter
Comments are meant to help the reader of a program. They do not help by saying things the code already plainly says, or by contradicting the code, or by distracting the reader with elaborate typographical displays. The best comments aid the understanding of a program by briefly pointing out salient details or by providing a larger-scale view of the proceedings.
Let's define a constant in Java
private static final int DEFAULT_WINDOW_WIDTH = 640
That won't be needing any comments.
Very true.
In _The Mythical Man Month_, Brooks wrote (paraphrasing here): Comment your code and I will remain confused; comment your data structures and your code will become obvious.
Example: in one of my multi-threaded network applications, rather than call inet_ntoa to convert an address to dotted-decimal form, I in-line that code with some bitshifts and bitmasks. Any C programmer who will be working on a network application will probably know what it's doing, but why not just use the library function? Well, it's not thread safe and our installation doesn't have a standard thread-safe version available.
So that one gets the comment.
I generally comment any loop and explain what we're iterating over, and what we're doing with each element. I generally lightly comment the beginning of each function and explain what values it expects to receive and what it will possibly change.
It's easy to write self-documenting code in C. If people used const qualifiers more when they pass things around, code would be a lot more readable. I spend more time figuring out where some random variable gets modified than doing anything else.
The other thing I comment carefully is any pointer arithmetic or tricky pointer use. Even simple things like pointers to pointers ought to be documented. I assume that whoever is going to come modify code once I'm done with it has nothing but the source to look at to figure out what it does. I avoid leaving comments that inform the programmer to look at some external file or manual that they may or may not have access to. Why? Because I keep running into code that does just that and I can't even find the docs they're referring to.
I think fairly brief, detailed comments are helpful. I also try to comment anything I do that will work but is bad technique or uses non-standard functions or what not.
I use Vim primarily, and I'm beginning to switch to using Emacs for coding.
Vim has the most wonderful autocomplete hotkeys; type the beginning of the function/variable name, then press Ctrl-p to search up and Ctrl-n to search down through the file, buffers, etc. Now, long variable names are actually usable for 80wpm typists like me. (I'm around 40-50 for plain text).
Does anyone know what the equivalent (or at least sorta-equivalent) commands are in Emacs?
-Chris
The problem at Microsoft isn't the programming staff not practicing what they preach. It's the fact that schedules, feature lists and release dates are driven by Marketing. Software developers are second-rate citizens after the marketing goons. It doesn't help that the carrot at the end of the stick is a shiny Ship-It award.
I used to work for Microsoft, but I feel much better now.
- name and address withheld by request
http://www.pablowe.net/standards/index.html
My favorite was actually an error message; a piece of (commercial!) software crashed, with the error message:
"Dave says this case can't happen."
http://mindprod.com/unmain.html
and "man 9 style"
In comments, I think it's most helpful to explain the "why's" of the code, (i.e. :
SomeClass someObj = null;
// log but do nothing, conditional block will
// handle this along with related problem 2
// don't show the user our stack traces
try{
someObj = someFactoryMethod(someInput1);
}
catch(SomeExpectedException expected)
{
LogMgr.logWarning(expected );
}
catch(Exception unexpected)
{
LogMgr.logError(unexpected );
rethrowUserSanitizedError( "User-sanitized message");
}
if(someObj == null || !someObj2.someCondition(someInput2))
{
showInvalidInputMessage(so meInput1, someInput2)
}
I think this helps prevent another programmer's incomplete understanding of the "what" causing them to overlook consequences of making code changes.
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.
Code should, so far as possible in context and langauge, be self-documenting, which is to say: the code by itself should lead me as far as it can in understanding. Good, well-designed OODLs make this somewhat easier than more traditional straigh-line imperative languages, but all high-level programming languages are capable of such practices.
This means coding standards -- all code doing substantially the same thing should probably look the same. Indentation style should be sound and consistent, and unless strong countervailing arguments exist, all procedures should be very short, very well-named, and be very straightforward. As others have noted, variable names should be as precise and accurate as possible -- and, believe it or not, naming variables and procedures properly all the time is VERY hard.
When code gets written, and you start smelling the "smells" of imperfect code, this means it is time to refactor: move variables out of objects to where they belong; collapse classes where appropriate, or break them up where appropriate; rename procedures. break procedures up to clarify (and rename), consolidate procedures to clarify (and rename) and so forth.
An excellent book on refactoring is "Refactoring" by Fowler. Refactor until you shouldn't refactor any more. Then the code, sans smells, should read like a charm.
Then, and only then, will you know what the comments need to say. Comments should be things not possible to express in the code per se, or which couldn't reasonably be understood without deeper analysis. For good, well-factored and self-documenting code, most comments are usually tight, short, rare and VERY helpful. Indeed, most comments in good well-factored code are usually unnecessary for experienced readers -- and too many comments actually get in the way of reading the code.
One last thing -- keep your code comments current. Too often, changes are made in code without countervailing updates in the comments (since compilers tend not to pick up such things. The single worst possible thing is a comment that is wrong. Worse than not commenting at all. And both are heinous. Almost as bad is commenting superfluously or too much.
My view -- write your code right. Then, the comments, when necessary, will be apparent -- kinda' like the code became apparent from writing right.
I'd rather the code point out the obvious for me rather than reading the comments and reading the code. I would recommend reading "Refactoring" by Martin Fowler(?) though not really end to end who has time for that.
// TODO: convert switch to polymorphism
// TODO: FUGLY CODE, fix ASAP!
I generally would use comments to mark off candidates for large refactorings, e.g.
To be honest, I don't really write code that is that readable to other people or myself sometimes. I am still human and I make mistakes. However, when I revisit my code or touch someone else's code, I try to reorganize the code and refactor things.
Some people may disagree and say that these would slow down the application. However, if the code is more understandable, other optimizations can come about which are cleaner. Plus a good compiler can do a lot of optimizations for us already.
However, the opinion above is only for application code. Meaning no really complicated algorithms that require a lot of math to understand. Though I rarely do algos anymore anyway so does not really matter.
If I had to deal with algos, I think rather see someone do it in tangle/weave but the code has to be to the point, just the jist of the algorithm. The tangle'd code will just be added to the library since it can be reused elsewhere.
I'd welcome your opinions. Thanks.
Archie - CIO-for-hire
Search the web for "SERTS"
...who make reviewers like me stare at computer screens for endless hours trying to figure out how the hell your computer code is supposed to work.
// Creates hash table ". Question: Where does that leave me? When I find out that there's some problem in the hash algorithm, I have to dig through 200 lines of code to find some freakin' bug that is described only by "Creates hash table." Your example of why comments don't need to be made is a poor one:
// increment loop counter
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.
Some variation of the methods described in "Literate Programming" by Donald Knuth are a good place to start. In summary, Knuth says that you should be able to extract from the same source both machine instructions, and a human parsable document, with unusually high importance placed on the later. Whether or not you want to imbed LaTeX into your document is up to you (I never have bothered), but on the whole find something that will make your code and algorithms understandable to another programmer who's never met you (because that's probably who will be either grading or maintaining your code at some point).
I once wrote some code in Command level CICS-COBOL that used GETMAIN and FREEMAIN to do dynamic memory allocation so I could take a data structure in a file (by order.item.warehouse.quantity,) and stand it on its ear (by warehouse.order.item.quantity,) to get at the data that way.
It worked fine and I documented it and the BLL cell layouts properly but the CONCEPT of dynamic memory allocation proved to be the stumbling block.
I ended up giving a course on my hack and they still didn't get it. I eventually left the company and left them with working code that they were not intellectually capable of modifying. I didn't feel good about that.
Sometimes they don't understand one concept (object instance relationships) and sometimes its another (state machines) but I always seem to encounter people having problems that they are too busy struggling with to see that the problem lies with their application of an innapropriate solution.
AND THEY AREN'T MENTALLY EQUIPPED TO PERCEIVE THE TRUE DIMENSION OF THE PROBLEM. (Not its metric, [I didn't say SCALE of the problem,] but its topology.)
There is bugger all to be done in those cases.
Being ignorant of the uses and applicability of state machines leads to combinatorial explosion of GUI (and supporting objects) code to handle different state transitions.
Rather than maintaining the state machines, (not even the engines but the state transition arcs and nodes,) they were ending up replicating GUI code.
That was really fucked up. I was asked to resign. I did, heaving sighs of relief.
(And then somebody used the building as a landing strip. Yeah. I'm still fucked up about that...)
MSBPodcast.com The opinions expressed here are my own. If you don't like 'em... Think up your own stuff.
One of the best examples from my personal experience is a fairly large 8-bit assembly language project I did (for an embedded PIC16C76-based product). The project has approx 25000 lines of assembly code distributed in about two dozen files (which built about a dozen different flavors of the product, though virtually no code was duplicated due to common code being used by includes... it really was about 25k lines of assembly!)
The first time another programmer worked on it, he of course complained that it wasn't commented very well and lacked documentation.
In fact, a quick grep ';' *.src | wc compared to a wc of all the files revealed that 34% of the lines had a comment (the vast majority the whole line was a comment, as I tend to write blocks of prose above sections to explain what they do, rather than a comment for each register move).
But if 8500 lines of comments wasn't enough, there was an 11-page document I wrote about the design of this firmware... about half of it was a "roadmap" that described the "larger picture" of the firmware and how it was arranged into the various files. The other half documented specific tricks (like a 6-instruction sequence including a skip-past-a-skip that achieves a 16 bit add/subtract in that PIC part which lacks carry input). There was also a lengthy discussion of the overall strategy for managing the various bank-swapped memory of that processor and some other stuff about the real-time performance (that was a hard real time application).
Learning is painful for most people, and learning someone elses code seems to be absolute agony for many engineers & programmers. They always complain that you didn't document/comment the code enough, even in an extreem case like this!
PJRC: Electronic Projects, 8051 Microcontroller Tools
Lots of posts on quantity of comments and theres a bundle of good arguments for both the more-is-better folks and the dont-overcomment advocates. Similarly the drive to make your variable names meaningful is worthwhile but the one addition to any code, be it perl, C or anything else, that makes maintaining it easier has to be the humble newline.
The important thing is not how many comments of what type but the overall layout of the source so that it is consistently understandable on reading through it. If a comment is required to accomplish that then insert one. If, OTOH, all you need to do is break up and indent the lines a bit more intuitively then do that rather than trying to explain the more awkward structure in a comment.
Sure, you can easily pack a fully functional perl script into a 4-line .sig if you want but a 100 line script thats as squeezed together as it possibly can be becomes unreadable no matter how many comments are inserted into it. If a single line of code does more than one step in your program then consider breaking it up. If it absolutely has to be one line in order to work then backslashes are your friend. The guy that reads your code to find out how you did that after you've moved on to bigger and better things might be an entry-level hire who has enough of a learning curve to cope with without wrapping his/her head around tightly compacted code as well.
Remember how simple you kept it when you first started learning a language? Keep it that way when you're more experienced unless theres a reason to do otherwise.
I had a
I've noticed that the exerience of the programmer, like most aspects of software design, is only an asset if the programmer has done a variety of tasks. I've seen veteran programmers who have only written code and actually never maintained it. They never actually learn what maintainers need to make modifications, so the comments only help them write the code.
My best advice is to do as many tasks in the software development process as possible. This includes testing, maintaining, and working with users and even technical support (gasp!). Don't get stuck doing one thing. You won't get better and better at it, you'll become more out of touch and therefor do an even worse job.
Experience is best measured in deversity, not years.
-- Ken Kinder ken@_nospam_kenkinder.com http://kenkinder.com/
If you define structure with public stuff but default, why the hell are you using 'class'? Use 'struct'. The only difference between 'class' and 'struct' is that 'class' has private members by default, while 'struct' has them public by default.
Why should he? He's not writing C. Why should he have to double the syntax when, as you said, 'class' would do the exact same thing? Maybe it's better that he explicitly has to make everything public. Maybe he thinks, as do programmers in most other languages that support classes and struct, of structs as being mere aggregated data and classes being actual object definitions. Or maybe he just likes browsing through classes by searching for "class " in his editor. Just because the language supports something doesn't mean he has to do it, especially when it actually reduces the value of the code.
I've finally had it: until slashdot gets article moderation, I am not coming back.
I'm sure I have more of these somewhere but these are off the top of my head. Besides, I'm in danger of violating my own "Keep comments brief" rule. If I think of more I'll post them later.
Insert witty saying or aphorism here.
The Indian Hill C Style and Coding Standards is probably something everyone who codes should have read at least once:
http://dogbert.comsc.ucok.edu/~mccann/cstyle.html
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.
Think of your code as a document that describes how something is done. Always imagine that it is being read by an intelligent person who doesn't already know how or why this thing is done in a certain way.
Oh, and never define words in terms of themselves. This is not helpful:
Consider: if you saw a definition like this in a dictionary, you'd laugh out loud. Every definition should either (1) completely avoid all the words in the term being defined, or if that is too cumbersome, (2) have a reference to a document/glossary/whatever that describes those words in more detail. If your project has no such glossary, it probably needs one.Patrick Doyle
I mod down every jackass who puts his moderation policy in his sig. Oh, wait a sec....
It's simple:
Use COBOL!
Stupid people will be persecuted to the fullest extent allowed by law.
I read this brief classic a long time ago in Math 131 (Intro to Fortran) and it set my style for the rest of my carrer. The quality of clarity in programming is independent of the language used. Besides all the excellent advice others have posted, I'd keep this principle on mind:
The source code is not only instructions for the machine, it is the most important means of communication between the software developer and the (eventual, inevitable) maintainer. Ask yourself, "If I sent this code to another developer who's completely unfamiliar with the project, would they be able to quickly understand what it does and how?"
Hm ... I find the following observation interesting:
.... writing program code is mentaly a thing where you fiddle with the HOW.
... even if the code is hard to understand.
... if we need x == y, suddenly we should write WHY we need that)
// increment i
...
.... coders should do the same.
... and dropped it some 4 or 5 years ago.)
:-(
Most programmers (especialy those without formal education) find programming more an art than an engineering task.
If you talk to them about a "software project" they imediatly tell you HOW to do it and skip the "analysis phase" in which you usualy try to figure WHAT is needed.
Another thing, similar interesting is: how do you teach or how do you learn?
The best way is to start with the WHAT. That means simple facts, like: "a programming language supports the concept of storage and the concept of instructions(usualy)".
Supported with simple examples.
Then you teach the HOW. How to use the concept of storage? How to use the concept of instructions?
Supported with simple examples.
Finaly you teach the WHY. That means you teach the principles which lead to "the physical laws", efficiency, beauty or in depths insights. E.g. why to use a guard element at the end of an array while searching the array with a loop.
If we go building a new application for a customer we usualy do an OO analyis and a OO design. (If we are engineers and not artists)
That means we first analyze the WHAT. What is the application supposed to do? Then we can go deeper and analyze HOW is the application supposed to do it?
So far we are far away from code. We only found classes, some attributes and some few methods. Because we looked only on the WHAT. The HOW, we looked on so far, was only the user point of view.
If we shift to design, to actually get closer to the code, we more and more concentrate on asking us HOW. HOW will it work, HOW can it work, HOW should/will it be implemented to work. From the domain constraints of the application we shift into technical constraints of the run time environment and the implementation.
So
How to get a new customer into the DB? The code describes how to do it
The first goal in coding(the foundation is layed by the analysis) is using good class names and good method names(or the equivalents if you program not oo).
This gives you an insight WHAT you want to achive.
While you code you fill methods and add methods(if you otherwise would write to big methods) and craft HOW to achive it.
So, what should a comment now do? The comment is needed to fill the gap, or to express the third point of our mental model we make: WHY.
OOPS? Yes, we know WHAT we want, we know HOW to get it, but WHY do we get it in that way?
Comments are needed to express WHY we in certain cases drop a habit. (e.g. most for loops in C/C++/Java have for(;x less_than y;)
Several posters pointed out this is a dumb comment:
i++;
Right! But it is not dumb because it is obvious what i++ does, or because it is superfluvious.
It is dumb because it explains the WHAT. It says: what the line of is code doing.
Unfortunatly comments like that are used in language teaching books. To TEACH coders that "++" means (post-)increment.
New coders learn by that: you have to comment like this.
So again: don't comment the WHAT. Comment the WHY.
In teaching OO my rule of thumb for method sizes is: it needs to fit on the screen of my lab top.
As I beam with my labtop onto the wall, I use a big font, like 18. Methods then have a size of 8 lines or so.
If a method gets longer, you usualy make sections and write a comment on top of that section, do you?
Well, thats an excellent way to extract a method name from that comment and to put that section into a "protected" method.
With having more methods, some of them protected and factored out of otherwise to big methods, we suddenly get more freedom to "modify/extend" derived classes. And: oops, we suddenly are close to use a well known design pattern: Template Method. The big method is smal and calls several small methods. The big method is the Template Method, the smaler ones are hook methods. In a derived class suddenly I can moddify such a single step of the algorithm by overwriting a hook method.
So, now you probably have a class with 25 methods?
Probably you should divide the class up then
The art of OO Analysis gives you the insiged to realize early that a class mixes two concepts and therefor should be split up into two classes.
E.g. keeping all attributes of an author in the book class, just lets the class explode and is wrong anyway.
The ART OF OO PROGRAMMING is to anticipate such refactoring points and to use them wisely when appropriated(and not to use them when not).
Programming in itself is no art. Just like painting in itself is no art. Artist usually studdy 10 years and more under the guidiance of other artists
My programms have nearly no comments. Except for classes, WHAT is it for. Methods and their parameters, WHAT are they for, and sometimes HOW do they work.
If a method body is not clear, or if I feel I should do it, I explain WHY I do certain things like I do.
Except for counters all variables have long explaining names. Methods and classes anyway.
I do not use index variables like "bookCounter" because a loop like:
for (int bookCounter=0; bookCounter less_than MAX; bookCounter ++) {
if(found(book[bookCounter]))
return book[bookCounter];
}
meets my criteria of: it does not give any benefit. I see WHAT is going on, and there is no special need to explain WHY something is happening.
A simple 'i' is good enough. (I used for more than 10 years variables like bookCounter
The hint, pointed out by several posters, to use assert() instead of comments is absolutely valid. Drawback: tools like doxygen and javadoc, do not transfer those asserts into the outside method documentation. So by browsing HTML docs you do not see it.
If you have to dig into the code anyway, an assert is much better than a comment. Especialy if you have a test suit triggering your asserts.
To bad, realy to bad, that SUN went for an assert facility in Java 1.4 and did not use pre- and postconditions like Eiffel
Regards,
angel'o'sphere
Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
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.
I write all of my comments in haiku.
comments in haiku
not for any good reason
i was really bored
Ok, not a really good example, but you know what? No one's ever said anything about it.
I use habits learned from Code Complete every day, such as taking the time to choose a good name (no, I'm not talking about Hungarian notation). The single most important point of the book is that people read code, too.
I found Writing Solid Code, another Microsoft Press book, to be less enjoyable. It was, however, worth its price for one C habit I've retained: put the rvalue on the left in equality tests. For example: if( 0 == foo ). Why wait until run time to find that you've accidentally assigned, instead of compared?
As to "junk food" in programming, I prefer to categorize all of that as "rapid prototyping."
Often the coder can describe the program in one-on-one discussions far better than he can write a detailed description or remember to add comments.
In this case, get one of those speech-to-text programs like Dragon or Kurtzweil or IBM and have the programmer go through the voice training. Then have him (it's almost always a him) do a long description of the program in voice and append the text generated from the speech to the code.
If this is too much of a hassle then simply use a boom box to voice record the programmer throughly describing the code and convert the recording to a mono voice quality MP3 file. Include this MP3 file with all of the other files of the project. Better yet, link the sections of MP3 description right into the code. This entails having a second source code file that isn't ASCII, but it's the 21st century and it's time to upgrade these old text-based inflexable compilers to multimedia input/output.
This is quick, easy, and a whole lot better in the long run than incomprehensible comments scattered in the source. Programmers and project managers have to start thinking 'outside of the box', especially since programming is the most conservative (and reactionary) sector of the computer/electronics industry.
Anything written in Perl.
Try Meta or Alt + '/'
In fact I never create a new function/method if it's only going to be called from one statement.
Never? What about interrupt handlers, or other callback functions? Those are only going to be called from one statement, inside another function. And what if an embedded system (such as Game Boy Advance) has an area of slow memory and an area of fast memory? Sometimes, you want your main game loop to be in slow memory, with certain inner-loop functions (the audio mixer, etc.) in fast memory.
I've seen functions broken up like this where a subfunction is called within a loop, which demonstrably sucks CPU cycles (pushing and popping registers over and over again is no way to optimise).
Many architectures (x86, arm, mips) place the first four arguments in registers anyway.
Will I retire or break 10K?
This is a good framework. Your code is probably very pleasant to read. I might argue with your position about marking changes, however. There are times that it's highly useful to see why and when a particular block of code was inserted. Basically, if it's relevant to understanding or troubleshooting that chunk of logic, then by all means leave fingerprints.
One other suggestion you didn't make was: Write the comments first. In The Old Days this was much more important, when working e.g. in assembly language, C6, or FORTRAN. But it's still very helpful. As you start writing the code, implementing your abstract design, you pass through all the major decision-points that shape the detailed implementation. It's relatively easy to capture those decisions as you rough out the module, explaining macro control and data flow, algorithm design, etc. Later comments tend to focus on the gory details rather than the big picture.
Another suggestion is: Revise old comments. It's easy to let old comments go out of date, particularly module-level and block comments. Part of the revision discipline should be reading through the existing documentation and making sure it's (still) accurate. If not, fix it.
Two more: Design and use a set of standards for naming, module headers, error handling, diagnostic messages, etc. These things don't evolve; they have to be implemented by choice and agreement. And Use whitespace intelligently to ensure that important things are easy to see.
-- We all have enough strength to endure the misfortunes of other people. La Rochefoucauld
Here's a code segment from the linux kernel demonstrating good commenting practices (from file /arch/sparc64/kernel/process.c)
dump->magic = SUNOS_CORE_MAGIC;
/* fuck me plenty */
dump->len = sizeof(struct user);
dump->regs.psr = regs->psr;
dump->regs.pc = regs->pc;
dump->regs.npc = regs->npc;
dump->regs.y = regs->y;
memcpy(regs.regs[0], u_regs[1], (sizeof(unsigned long) * 15));
dump->u_tsize = (((unsigned long) current->mm end_code) - ((unsigned long) current->mm->start_code))
"Quoting famous computer scientists out of context is the root of all evil (or at least most of it) in programming." - K
I discovered the hard way that sometimes a call to a routine is actually larger that the code for the routine itself, at least using code warrior for the palm.
Does your compiler support the 'inline' keyword? If you are using C++ or C99, it supports 'inline'. If you are using 1990's C in a recent compiler, it probably supports 'inline' as an extension.
Will I retire or break 10K?
Before you start groaning, this does *not* necessarily mean that you
/* Swap entries i and j in foo array. */
must generate N lines of comments for N lines of code.
Example:
int temp = foo[i];
foo[i] = foo[j];
foo[j] = temp;
I consider it okay to be "lazy" and have one comment line to describe
multiple lines of code.
The idea is to make sure that the "comment coverage" covers all lines
of code.
Take away all code and you should have the pseudo-code describing what
you're suppose to do. Think of it of being a redundundant way of reading
the source file. The programmer can either read the code or your comments--
whichever is easier.
-cmh
1) All methods(functions) are named in the pattern ObjectAction (like invoice_create or InvoiceCreate if the language standards are mixed case).
2) All functions have a standard header. This includes name, parameters, return values, side effects, purpose, notes (how it gets done) and revision history (a brief one liner, the change logs give more detail)
3) All variables are declared upfront, with descriptive names, and if required a description of how they will be used.
4) All functions are alphabetically listed in the source. If you followed 1), this should put all relavent code close together.
5) All functions are fully responsible for the Action they purport to do and do nothing besides what they purport to do and their names reflect this.
6) Where appropriate, special inline comments delineate major parts of code ("Determining destination", "Calculating taxes" etc.) These sections are typically good candidates to concider for breaking out into separate routines.
7) Other in-line comments always exist where it is not obvious what or why you are doing something, but never exist if it is obvious.
I have been programming for about 25 years and these generic rules are appropriate for just about any language or environment I have come across. The biggest rule is if you are working on an existing application, don't change the style to suit yourself. Program in the style that has been established for that application. Nothing worse than trying to debug an application that has 15 standards because 15 programmers have worked on it.
To me, well documented code means that someone who doesn't know C can read my C source code comments and port that application to their native programming language easily.
/* and */, but it does mean that every section of code should be well thought out and well described, not in techno-speak, unless absolutely necessary.
They don't have to look at the source itself at all to get a good english undstanding of what each part of code is supposed to do.
This doesn't mean you should write a ten page paper, all within
These comments would be good to describe what the variables are, and what is happening to them in the code and why that's important.
Too early in the day to continue, but I think I've blathered enough.
Greg
We have always required, in our corporation, a 3 to 1 ratio of inline documentation to code. What that means is... if we count overall comments in code to lines of actual code, we should find roughly 3 times the number of comments to lines of code. This does not mean that each and every line is commented... but that SECTIONS are well comment and clear.
Now... holding to a *fixed* amount of comments does not make for good comments... but it DOES require the programmer to PRODUCE comments. So what does make for good comments?
- Comments should be used where ever code might be confusing, or where you do something in a manner that would make the reader say *gee, I could do this more efficiently* - to tell the reader WHY NOT.
- Comments must ALWAYS be written WHEN THE CODE IS WRITTEN OR CHANGED. Why? Because if you say *well, I'll go back later and add the comments* - later NEVER happens. Period. Thus comments MUST be placed at the same time code is written. We prefer to see the comment occur first and then the code - because while writing the comment you often realize something about the code itself.
- Comments are NEVER for the coder. They are for OTHER coders. So, when writing comments we must be careful to think *does this explain what happens to someone who has never seen my code or coding style before*? If not, rewrite the comment till it does. The point of comments is to make code MAINTAINABLE even when the original coder is gone.
- Comments should NEVER be placed in a separate document. They should ALWAYS be placed in the code itself. Any company who spends weeks/months writing up detailed documents that describe code are simply wasting time because the code will NOT reflect the documents. When making changes, a programmer won't stop to think *gee, I wonder if I need to change the separate documentation too*. But if the comments are in-line with the code than it is much simplier and clearer for both the programmer and others to maintain.
- Humor. Comments should contain programming humor. Why? To make it enjoyable to read and write. Quite frankly, I *LOVE* writing comments. Not only does it make it clear in MY mind as I code, it is enjoyable to read later. By introducing humor into the code you actually help to promote comment coding (e.g., make it fun) and also comment reading (e.g., READ the damn comment before you make changes)
- Comments should ALWAYS preceed the code it describes. It should NEVER be after the code it describes (Duh)
However, there are more to comments than just this. Coding style must also be taken into account.When I was learning computers years and years and years ago... self modifying code, self modifying data segments, and the use of GOTO's were encouraged. Shortly after I left college, colleges started teaching that self modifying code/data and GOTO's are EVIL. Why? Not because they are REALLY evil... but because middle management couldn't read code. This is why we have attempts at OOP and other stupidity... because middle management can't read code.
So... we say *don't use goto's* but instead we make tons of flags and nested IF's and checks to break out of conditions. Now... a simple WELL COMMENTED GOTO is much more efficient, and less wasteful, and less bug prone... than making a bunch of flags and checking them in numerous places. But students were taught to use flags, etc.. because middle management couldn't handle a GOTO. Case in point... let's say your in a nested WHILE() statement... and in there you are in a series of IF statements... and a condition occurs and you want to break out of the entire set of whiles. Well, if you use a GOTO, it's one line of code - which relates EXACTLY to one line of assembly. However, if you use flags... its a variable that has to be maintained... and checked in a couple of places, with breaks. That's LOTS of code and LOTS of possibilities for bugs. Inefficient and bad. A simple WELL COMMENTED goto would have saved quite a bit.
Other coding styles are also important to think about when commenting and coding. For example, consider this chunk:
- if (somecondition)
The above line of code is how many people are taught to program. That is... put the curly bracket on it's own line.{
do something here;
}
But this is much clearer:
- if (somecondition) {
Why? Because in the second example it is IMPOSSIBLE to accidently put a line of code below the IF, and have it interrupt the curly. For example...do something here;
}
- if (somecondition)
In the above example some programmer didn't look at the code carefully and pasted his formula under the IF instead of above... because the curly bracket is on it's own line, this changes the meaning of the IF entirely. The formula now becomes the IF clause... and the curly bracket expressions will ALWAYS be executed. This will be VERY hard to catch. But by putting the curly bracket at teh END of the IF statement, instead of the next line, only for formula will be incorrect and will be easier to catch.a = b + c;
{
do something here;
}
Does this have anything to do with comments? Yes... because CODING STYLE can in itself act as a comment!!
The bottom line for comments and coding style is that they should NOT be written for the programmer who wrote them... they should be written for the programmers who have NEVER seen the coding style and code before - and have to maintain the program. The comment must be explicit... clear... and up to date.
Soap Box Off
...Whos code I always have to work on!!!!
one comment every physical file.
What'a your next great suggestion? "Don't update the techincal spec or the functional spec because you don't have time because that triples the amount of work you have to do if the code is also commented. Just ride in like a code cowboy and make the changes you need".
I agree that if the next person doesn't change the comments, it makes it harder for the next person that has to work on the code. SO MAKE SURE THEY CHANGE THEM. If they don't, they're not really the kind of coder you need around.
In the past, I've modifier existing comments likes so.
//orginal comment
// modifier by SCK 2/1/2001 - fixed possible buffer overrun in var m_intInput
It didn't take me that long to write the comment and the guys that worked on the code after me appreciated it
"For a successful technology, honesty must take precedence over public relations for nature cannot be fooled." -Feynman
The other, more important comment is to list the assumptions being made. The relationships between objects, functions, the user, hardware, other software, etc. So call it local comments and global comments. Most local comments can be derived from well written code and are redundant. The problem I usually have with code is too many local comments and not enough global comments. Global comments tend to be the ones that you would find most useful in your own code if you go back and look at it after a while. For instance, why is it ok to do something that is counterintuitive from looking at the code. Or why do these certain side effects need to happen in this function. Or anything else that relates to program flow instead of function flow.
Global comments are also the most difficult to write. Sometimes we forget the assumptions we make, or are not even aware of them at the time because they seem so obvious. Global comments often seem like the kind of information that would be in a design spec or code documentation, but I think they also belong in comments. For instance, I like to see a very detailed description of functions listed in public header files. The information should be mirrored in documetation, but if I am in the middle of writing code and I am looking at a header file anyway, it is very convenient to find more than the prototype of a function.
So anyway, the standard I would like to see is significant documetation in headers, and reasons and assumptions in source. The comments in headers should contain enough information that you should not need to look at the source or the documentation unless you need specific implementation details. You should be able to call a function or use a simple object. The comments in source are for someone else maintaing the code, not calling the code. It should describe assumptions made, pitfalls of adding or removing functionality, standard ways to extend features, relationships and dependancies between this and other components, and everything that you need to change the code.
So, headers to use the code, source to change the code, is my suggestion for comments. For languages without that distinction, prototypes to use the code and source to change it, or comments to use the code before the implementation and change the code intermingled.
Here is some of the informal "rules" I've
adopted over many, many years of writing code:
* Declare _important_ variables on single lines
with a comment describing the purpose of the
comment (started with Fortran code continued into
C and Perl)
* Preceed "blocks" of code by longer comment blocks (set off by blank comment lines) providing a description of what the code block or loop,
or whatever is going to do. Particularly expand the explanation if the code is particularly tricky or clever.
* Document subroutines and functions by comment
blocks at the head of the procedure. This might
come before the procedure declaration or
immediately thereafter. It details that the procedure is to do and may also describe the
arguments. If the arguments to the procedure
are declared (i.e. C), then declare each on a
single line with a descriptive comment.
* Files/modules usually have a comment block at
the top which tells what the file contains,
why it exists, contains the copyright declaration and often has a section to record modification
history (each one line with version #, date,
initials and description of changes which might
make the "line" into multiple lines).
* Comments in the code are indented along with
the code.
Dr. Frank J. Nagy Fermilab Computing Division Authentication and Directory Services Group
Once code is separated amongst multiple files, classes, function liibraries, etc, it will become difficult to follow.
My personal experience has shown that explanatory paragraphs and high-level steps should be in comments, and an explanatory logging statement per 1-3 lines of code with variable states will handle the rest. The best thing about the logging statements is the ability for someone to track a program's execution flow and truly see what is going on. Any decent logging framework will be able to optimize the code for debug vs. production execution as well.
Hey, I'm just your average shit and piss factory.
FWEB uses your compiler(s) to compile the source code. It will use TeX to make your comments in the source code into documentation, with the source lines included (or not, if I recall correctly). This way, one file contains the code and the documentation. If you change the way it works, you can at the same time change the explanation, and the documentation; all three are there together, staring you in the face.
It's GPL, so you can use it freely, and tweak it if you need to, but it's been around for a while and probably won't need tweaking.
Spreadsheet
flight
simulator
Use a tool like doxygen to formalize your comment formats. The Mozilla project has a page for their doxygen-generated documents at the Mozilla/SeaMonkey Code Documentation and Cross-Reference.
In the Java world, Sun has a couple of documents on how to comment code, How to Write Doc Comments for the Javadoc Tool and Requirements for Writing Java API Specifications. Note that the latter references Object Class Specification by Edward V. Berard, Essays on Object-Oriented Software Engineering, 1993 Simon pp. 131-162., which is an excellent read in general.
All that said, please read and live Martin Fowler's comments on coding style and comments in "Refactoring: Improving the Design of Existing Code"
All variable names should be variations on "xyzzy". Examples are "xyzzy1", "xyzzy2", "xyzzy3". When you get too many of those, you can start putting the digits in the middle: "xy1zzy", "xyz3zy". And you can also vary the capitalization: "xYzzy".
Finally, if you still need more names, you can use "plugh".
These also make good passwords.
You don't let the client shove those things down your throat at the last minute. You tell them, "Either the date has to shift or we have to leave out this feature until later."
/. land. "But the client MAKES us put the feature in and THEY control the MONEY". I've been in that situation before and 9 times out of 10, once I've explained it to the customer that they will be getting a better value and more stable code by either slipping the delivery date or by letting us include and document the new feature and deliver it in a patch later they understand. Of course you get the occasional jackass that is on a power trip and says they won't pay if it ships late, that's why you make sure you're business is totally dependant upon one client. You make sure you have as many clients as you can handle so no one client can lord over you.
I know, I know I can already hear the chattering of keyboards in
"For a successful technology, honesty must take precedence over public relations for nature cannot be fooled." -Feynman
why the hell are you using 'class'?
Because this is Java and Java lacks structs
"We returned the General to El Salvador, or maybe Guatemala, it's difficult to tell from 10,000 feet"
comment stuff that is out of the norm or is a cheesy workaround to some OS or component bug. I often code for the Windows platform so my code is sprinkled with nuggets of wisdom like this.
// have to do it this way to avoid problem X
or
//tried it the suggested way but that didn't work so we'll do it this way. May revisit later.
Those are just examples, the actual comments are much more precise about the problem.
"For a successful technology, honesty must take precedence over public relations for nature cannot be fooled." -Feynman
First, let's discuss some principles behind commenting (or just documenting) code.
Is code well commented? Well, think of how long it takes to understand the code. Then, once you've understood the code, think of how long it should have taken you to understand the code, knowing what you now know. Why the discrepancy? Could it be addressed by better documentation? Probably.
So now you've identified poorly commented code. How can you comment code properly?
Let's assume you are coding with intent, and not by coincidence. You should have a plan, and know what you are doing, and not just be making it up as you go along. Think of it as shooting a movie with a script, and not improvising every scene. Well, the comments are your script. You should already have the (meaningful) comments before you begin. Write them first. If you don't have them, why? Are you sure you aren't just improvising?
Another principle is not repeating yourself. Say things once, and only once. Information should be in one place. So, if the comments repeat the code, that's a violation. Remove one: the comment, not the code. It's better to put the information in the code, and not in the comments. Save the comments for things that aren't as easily said in the code. That's why some movie scripts describe backstory and themes and influences that aren't explicit in the frames of the film.
Finally, why isn't this done? We all know we should comment our code for the next person, and when we are the next person, we curse our predecessor who didn't take the time to properly comment the code.
Why didn't he take the time? Better yet, why didn't his management force him to take the time? Let's face it, the reward structure is not set up for fostering well commented code. Management wants code that runs now, and doesn't care if some intern complains about lack of comments while maintaining it some months later.
So why should you comment well, even if management doesn't care? Think of it as a stamp of professionalism. You take pride in your work, so you go above and beyond what J Random Hacker would produce, because you know it's right. The code isn't done until it is commented and tested.
Anyways I just finished reading the book The Pragmatic Programmer and it has lots of practical advice. I've been coding professionally for six years and it still makes me want to reevaluate my work and see where I can improve it.
--
Marc A. Lepage
Software Developer
In case you are not familiar with it, javadoc produces a collection of html files automatically from structured comments within Java. It is a pretty good first pass for documenting code. I am sure that there must be some open source programs that will do the same thing for C++.
im just a measly ap student in high school but from my experience, pre and post conditions for all functions are infinatly usefull! also all classes should have comments describing their constructors, what they do and what their perameters mean!
*sigh* im sure i sound like a moron but oh well
Far too late to join this conversation, but let me add my $0.02 anyway.
What I miss most in most source code are comments that communicate the architecture and flow of control at the module level. When you get the source code for a project, it's generally a flat list of files. Where do you start? main() is not always the right answer - what's needed is an overall look at the code base and a guide to how it was put together.
Comments in the source rarely address these questions, being more locally oriented as a rule.
The most important thing to document is the purpose and usage of each class. This is usually best documented by including an example of the class usage in the class header file.
This becomes easy if you write a test for every class before you write the class. Then you can just copy the test code into the header file, and if you forget, then a programmer can simply look
at the test.
If you are having trouble writing the test, or describing the complete functionality of the class, then it is simply too large and should be split.
Well-named variables and functions can eliminate
the need for most comments. Rather than
writing
simply say:
and extract the fifteen lines into a separate function.
Do not abbreviate variable or function names,
unless you have a standard set of abbreviations
for your project that are ALWAYS used.
Try to write code so that it reads as much like
English as possible. Use noun-phrases for const member functions, verb-phrases for non-const member functions, and predicate phrases
for boolean functions.
Read Refactoring by Martin Fowler.
This way anybody can read it when it's neaded, and its presence is not distructive at all while reading the code.
It's so simple.
This site is the definitive source for information regarding developers.
http://www.echo23.com/domokun/
I urge you all to check it out immediately.
# wrote sig.txt, 23 lines, 31337 chars
well, when it comes to commenting my code, i always end up with:
code
strange code
absolutely weird code
black magic code
hard code {comment: works great}
--
"We regard you as if you were capable of mild *dissociation* reproof for minimal performance of assigned processing. We regard you as a *supreme command cluster*."
Greg Bear in "Blood Music"
the computer is online
i am not at it
what a waste of ressources
My favorite "useless" comment was one that was part of a (thank gawd) proprietary OS which had in the header to a chunk of assembly language "DOES NOT CHANGE REGISTER HL". The first thing it did was change register HL.
My point is that comments can be as much a problem as they can be a solution. If you have time to change the code, but no time to change the comment, then in essence you may as well have NO COMMENTS. Which really defeats the purpose.
I have found, for the most part, that GOOD function and variable names are FAR better than a half page of comments (as an example, take a page of C++ code and change all the variables to one character... see how hard that is to read?).
Second, ignore the law that says we can't exceed 80 columns. It is dumb. It is old. It defeats the purpose of having a HUGE SCREEN with little teeny lines. 80 columns are the size of IBM punch cards. AKA dinosaurs.
Third, kill whomever sez that Hungarian notation helps. It doesn't. It is the SECOND DUMBEST thing to come out of Microsoft. People who adopt it are mindless beasts of burden. You don't want to be one of THEM do you?
Fourth, BE FANATICAL about taking the what reads from others and discard what doesn't. I used to make boxes with slashes and dashes, etc. When I realized I spent more time "refixing boxes" I got rid of the boxes.
Fifth, is the best size for a bottle of gin. Gin and tonics may not help with coding, but they take the pain away from reading others code. Also good when the boss says "so, what the hell does this mean?".
Sixth, "standards" doesn't mean squat in the real world. Getting code out is far more important. Learn what is absolutely required for comments.
Seventh, if it is a trick TELL THE READER! Your audience is the next guy who has to support your dreck...er...wonderful creation. He is probably going to be less brilliant. If you use a trick of the compiler, LET HIM KNOW. I have worked (and written) code that dies a mysterious death when you "optimize it" - when in fact it IS optimized.
Eighth, learn from the screwups of others. If something you picked up reads like crap, then figure out how to make it better. Does it need to be indented more? Better variable names? Etc. Surprisingly, others probably had the same problem.
Ninth, NEVER write code with comments like "YES". I knew of a HUGE chunk (when printed is stood three feet tall) which had five comments in it. One was "YES". The contractor had to sit for several days with it remembering what it did before he could modify it. Mindblowing, isn't it?
Tenth, Keep evolving. Writing comments is a lot like writing code, you get better at it as you get older. And the style eventually gets more terse, but more reasonable. Eleventh, EVEN if it seems obvious, sometimes it may not be. Be prepared to defend what may seem like simplistic comments. Twelfth, This is the most important. BE CONSISTANT.
IANAL, but I've seen actors play them on TV
I write several languages, and thought I was pretty good at commenting my code. My boss was happy, my co-workers didn't complain, life was good. Then I took a job at a Java-shop, where javadocs were generated hourly for all shared library classes. Since I was writing shared library stuff, that put me in the limelight. I found I had many bad habits: My class descriptions were frequently too brief, and included no examples of how to use "Widget3.class". If I included multiple constructors, I frequently only documented the "most verbose" variant. Since my variables were hypothetically well named, it seemed superfluous to comment on what they did, even if I defined them globally and used them in multiple methods. The list goes on. The generated javadocs were used by other developers who depended on my classes for critical functions of their own projects. Surprisingly, they were unhappy with the "minor" omissions in my documentation, and suggested that I look at Sun's classes for a clue. After a hearty helping of humble pie, I actually learned to comment my classes in such a way that they were as useful as those written by the Sun programmers. Even though I still write perl, C++ etc. the commenting skills I learned with java are now second nature, and very helpful. Try using javadoc on your code, then READ the generated documentation - if it doesn't explain your class accurately, completely, and at a level that would let another programmer understand your program, you have more to learn. BTW- those in-line comments, while not picked up by javadoc, are absolutely essential for other programmers. If you have time to alter the code you most certainly have time to alter the comments!
I always wondered why the Software "AllClear" has not been used to comment code. It has a pseudocode language that is used to create flow charts. Looping and other standard constructs are there. Very simple really, a period at the end of a line indicates that the line is a statement, for example.
By creating the flow chart for your code with that pseudocode you have a verifiable set of instructions that can be turned into comments by simply adding a "this is a comment" string in front of each line with a stream editor.
Then you can build the code needed to implement the pseudocode between the appropriate comments.
Later, you can always add comments or extract the comments at any time (think grep) and recreate the flow chart to check (or figure out, if its someone elses code) what is going on.
VG
do not run strip on generated executable
What policy reason is there not to run strip on generated executable?
Will I retire or break 10K?
Take a look at these files. 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[])".
if you can't write the user-manual from the spec then the spec is incomplete.
So you're saying the specification should include screen shots of the finished app on all platforms? What about the names of the owners of all trademarks used in the manual?
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.
Unless, when it comes time to maintain the software, some new hire goes in and changes the code without updating the comments in parallel. Then the code and the spec have fallen out of sync. It will happen.
If you're smart and use good tools you can selectively collapse and expand the in-source documentation
What free editor do you suggest?
Will I retire or break 10K?
I wrote a 3000 line perl program at my last company to provide a "floorplanning language" for chip place about a year ago (1.5 years after I left the company) I was told the program was alive and well and had been extensively added on to with few changes to the underlying data structures or processing routines. My old boss said my coding style and comments were the key to their ability to continue to use the code.
I was pretty damned pleased to hear that!
Bottom line, don't get fancy with the coding; it rarely saves execution time to use side effects or multiple operations per line, but sure makes it hard to figure out after the fact (even for the author).
- Leo
You don't use science to show that you're right, you use science to become right.
if you don't make the change the trader needs NOW, he has been known to physically punch programmers in the face, cos he just lost X million dollars.
I have found some of the tips in the Code Obfuscation Guide to be reasonably helpful if not entertaining. After all, no one else is going to ever have to look at your source code, right? (Browny points for anyone who can highlight each of the tips in this particular guide used by Microsoft.)
He who has no
If you do Java, do Javadoc comments - fill in @param, @exception, @return, etc.. Trust me, somewhere, sometime, someone will thank you.
Likewise, if you do C/C++, check out CCDoc and do the same thing.
http://www.joelinoff.com/ccdoc/
JoAnn
I used to hate when my professor would make us comment every single line of code for our projects. It made even the most programs take forever to finish. He even made us comment the brackets, oh the humanity!
/add
Seriously, comments should be just enough to explain what the code is for and how it does it. It is there to save time for the next person who comes along so they don't have to waid through thousands of lines of code to find something.
What I like to do is have a meaningful header at the top of each structure and function (class/method for C++ and then have minimal comments at the end of decision statements that direct the flow of the logic.
// This function returns a random number between
// 1 and 200
int someFunction()
{
int someValue = random(100);
int someOtherValue = random(100);
if (someValue >= 50) Is Greater or equal to 50
{
someValue = someValue + someOtherValue;
}
return someValue;
}
As a fourth year student at the University of Oklahoma in the MIS program, I have taken a few programming languages (including C and Fortran) and I have had different instructors attempt commenting quite differently. In my very first programming course, my C instructor didn't really care about comments, he made really no attempt to inform us of how/what/where to correctly comment, as for variable names, we could basically use whatever we wanted --seeing that I didn't know any better then, this is what I did (and have had problems remembering what this code was used for ever since.)...After that mess, however, I took a Fortran 95 class with a professor in the CS dept here--he had very stringent requirments concerning every aspect of the code (including documentation) which I found very helpful (however time consuming to do). I don't know if this applies to non-procedure languages, however, in Fortran, we were required to have a variable declaration section in which constants were listed first (with REALs before INTEGERS), then local variables (REALs before INTEGERs), then external variables for functions/subroutines, etc. We could not use any literal constants in the body of the program (except character strings) --we could only use named constants (declared in the variable section). We also had to make sure that our variable names had to make sense to someone who knows nothing about the program (which could make variable names incredibly long, however, in one's drunken stupor--one can still understand what they mean).
We also had to comment every line of Fortran code (that was meaningful) and before declaring our variables, we had to create a comment section that clearly listed and defined each and every variable name. At the beginning of the program and before each function/subroutine we also had to have a comment box stating the name of the program (function, etc.) and description of what it did. (for functions we also had to list any arguements being used.)
Although all of this commenting was rather time consuming and increased the length significantly, I found it was incredibly helpful when I have had to try to figure out the logic again.
Basically, avoid comments. If your code needs a comment to be understood, it would be better to rewrite it so it's easier to understand. -- Rob Pike
Unfortunately, this is rarely practical, but I find the most useful comments are written when I'm going back through code I wrote over a week ago. The reasons for doing things are no longer on the surface, and thus if there's something I look at and have to dig for understanding, then it needs better explanation.
6 years and you don't know how to comment code properly, if you have to ask this and you have over 1 year ex. you shouldn't be coding..
The Truth: There is no string:)
Steal random comments from other people's code, and sprinkle them liberally throughout yours. It keeps the PHB's who insist on minimum comment levels happy, and anyone who has to actually work with your code will have to so thoroughly study it that they'll understand it better than you.
Let's take for example, C++. If a variable is passed by pointer or reference, you need to document whether it is being passed that way because it is altering the contents of the object or for efficiency (Yes, I know about const. Do you know about the debate over logical const-ness, that destrys the usefulness of the idea?) You have to document allocation and deallocation strategies. You have to document how array limits are passed. If something points to an interior of a structure, you have to document that, too. Old coding habits pop up - like allocating booleans as bits in a word - you need to document those. And, oh yeah, make sure that you document whether the int you are returning is really being interpreted as a boolean, too. There are more examples, but that's enough to make the point. C++ requires more documentation because it has a richer set of ways to do things at the micro-level of the system, any of which that can be translated to the macro-level, where it has very little effect on the logic of the system, but huge effect on the way the system is coded and interpreted.
So my first recommendation is to use a language where less needs to be documented. Lisp or Smalltalk come to mind immediately; Java or Python in a pinch.
That is all.
... you should be able to type faster than you can think ...
The reason *you* can type faster than you can think may be that you don't think very fast.
Try "dabbrev-expand", normally bound to M-/, and if you like it you can search for more documentation on dabbrev (dynamic abbreviation) commands and settings.
I've found that the only code I really understand is the code I write myself. It takes me a while to understand someone else's code, ,even if it's well commented.
1. Your "improved" code is much less readable than the original. Whoever has to maintain it will need more time to comprehend it.
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.
___
If you think big enough, you'll never have to do it.
I may not be able to define good documentation, but I know it when I see it.
The Practice of Programming by Brian W. Kernighan and Rob Pike. ISBN: 020161586X The Practice of Programming (reviewed sometime in the past by slashdot) is an excellent read, I hand it out to people the right crappy code.
?
2) Why set THREE values equal to ONE constant?
3) What's wrong with:
When I write code (even code that nobody else will see) I write it as psuedo-code in comments first. That lets me get it straight in my head before I write the code. It seems to help -- it makes my coding go quicker.
My comments don't go as far as your examples. Instead of "loop through the employee records" and "print the record" I'd write "print all the records".
Software sucks. Open Source sucks less.
...stems from the fact that professionals are paid professional salaries. So, until I make as much as the CEO, you can fucking kiss my ass. If it's annoying, give us time to do it properly.
The primary goal of commenting is to save time by making it easier for a literate programmer to jump into your code and understand how it works.
A literate programmer doesn't need you to comment tricky-looking lines of code or to ensure every looper value is "iSomethingDescriptive" instead of "i". What a literate programmer needs is *context*--they need to understand the overall architecture of your code, how the small piece they are looking at fits into the architecture. This means you need to comment the goals of each method or function, the structure of each class/object/interface, by specying *why* you've broken things down or structured things in such a way or *why* a function or method is trying to do some particular obscure magic. This way you don't have people walking into your code, picking up a piece of it, and having absolutely no clue what it is trying to accomplish, why it's trying to accomplish that, or when it gets invoked.
This is why "write the comments first as pseudo-code, then fill in the actual code beneath the comments" approaches are generally successful--because they in effect guarantee that you've thoroughly outlined the architecture of your code in the comments.
One of my personal mantras when commenting is to make sure I am commenting on why I'm doing something instead of what I'm doing. The code will already show the what, so add something to that.
To illustrate this point, consider the following snippet of code:
line += 7;
Yes, the comment told exactly what the code does, but what are we adding the number 7. Why is this value special? Is it somehow related to the number being prime?
So, if the comments are just reiteratring exactly what the code is saying, don't bother. Give the reason about why something is being done.
//
.... ... ...
// What the heck does this code do...
//
// META: Why the heck did I do it this way...
//
Here's the key. Nobody wants to read obvious comments like "this function takes this argument...blah blah blah" or "prints this..." If you've written any amount of code you you don't need to see this. It is easy to figure out from the header or code itself. NOW, if you do need to pass some strange argument or return some strange argument or do something which looks obvious but may not be, put it in the comments. e.g. a pointer to a pointer to a pointer, whatever. They key now is to write a meta comment when you start doing abnormal coding. META: Why the hell did you do it this way. What were you thinking at the time. Why did you think this was the best way.
The key is the meta comment. This will tell someone maintaining your code what the hell is going on much more so than a bunch of terse:
input:
output:
what this function does:
It will tell the maintainer WHY you did it this way. Maybe it's because you were connecting to some ancient piece of hardware or software that required it this way. No other type of comment will convey this more than a META: comment just after the original comment.
Later the maintainer can easily see and realize "oh, that's why he did it that way. That's no longer true/relavent. It would be safe to change the code now."
I find the most useful comments in code are the ones that explain what you're attempting to do //return first instance of character in a string
eg.
That way when someone else comes along and tries to maintain the code, if they know a better more efficient way to code that piece of functionality, they can do so.
Too often I find myself not keen to modify a routine as although it's obvious what it actually does, I'm not sure what the original coder was trying to achieve, and I have to assume that maybe they are much cleverer than me and I've missed an important side effect that they specifically coded for.
To reiterate:
code tells you what it's actually doing
comments tell you what it's supposed to be doing
My variable name length tends to have a direct correlation with their scope. If I need a local loop index, I call it "i", since it's obvious from the context what it does. If I have some sort of global configuration variable, it's going to be named "targetSystemType" or something like that.
Just junk food for thought...
Norvig & Pitman have a lot of good things to say about coding style and commenting style. They deal specifically with Lisp, but one can easily generalize the first several parts of the presentation to any language. A couple of my favorite points:
It's All About Communication
Expression + Understanding = Communication
Programs communicate with:
o Human readers
o Compilers
o Text editors (arglist, doc string, indent)
o Tools (trace, step, apropos, xref, manual)
o Users of the program (indirect communication)
Some things to notice:
o People's style changes over time.
o The same person at different times can seem like a different person.
o Sometimes that person is you.
My
I find most of the problems with code is that it is badly architected, or just was a design in progress and NEVER refactored.
/* y=17*x */ - you must indicate the conceptual target of your "hand optimization".
/* ON */, someone will create three layers of objects to a universal idealized interface, then three more layers getting to the hardware, each in a different file, so Activate(Check); [which somehow goes to LEDOn which inherits something to actually do it, but the actual bits and port will be elsewhere] will be all you see and you don't know if the hardware is broken or which of the layers the error is in. You still can do the original line in C++, and it will be completely obvious what you are doing and what line or bit to test and what it does.
/ www.tuxedo.org/~esr/writings/taoup/
There are a few people I know that I can read their code much like a book and it can be completely devoid of comments. But the indentation, variable naming, subroutine splitting follow some very precise rules which I've seen elsewhere. It was to the point that in 15 seconds I pointed to an offending line of code after talking about queue structure (the code was the wrong of linear v.s. circular).
There is an aesthetic beauty to good code. The form follows the function precisely. There aren't any extra variables. This is probably the same as the Quality Plateau as stated in the programmers stone below.
The splits across files are also well thought out. Each file can stand on its own and would be reusable and self contained. They contain a lot of statics. The separation into the files is also along a minimalist interface - as few exports and imports.
Most of this is from a bi-weekly refactoring - new functions end up in the wrong file, or they are proven to work untuned, so AFTER IT WORKS part of the process IS TO MAKE THE CODE SIMPLE TO MAKE DOCUMENTATION EASY.
Complex code is hard to understand even with perfectly accurate (maintained) documentation. But this is where comments come in. If something is being done that is subtle or otherwise not immediately apparent from the code structure should be explained. For embedded targets, it could describe the hardware effect (e.g. the Check LED will turn ON).
Another area is to bypass a compiler bug (or anomaly - not all of C's behavior is precisely specified), so if x11 breaks, but x*2048 works, state that. Or to synthesize another operator, e.g. if you have 16*x around in z from earlier lines of code, and do you can do y=17*x or do y=x+z ;
The worst code I've seen - up to the totally opaque is usually in Object Oriented designs. This is NOT a problem with OO, but its misuse. Instead of LED_PORT |= CHECK_LED;
Three layers should suffice for most designs. A layer is a power as in the inverse of logarithm. So the complexity of 30 lines in one layer would be a complexity of 225 in two and 1000 in three. When you create a layer, you create interfaces across that layer. And you have to document the interfaces completely and precisely. It is easier to annul an interface than to document and maintain one.
Think about TCP/IP. Basically 4 layers including the application and physical. The problem with the 7 layer ISO model is that it was too deep. TCP/IP was simple, straightforward, and clear.
So as far as comments, they should indicate the exceptions - code that is dissonant from the aesthetic for a reason.
The rest (interfaces, data, etc.) should be clearly documented, but that doesn't mean as inline comments.
Very good resources:
http://www.ftech.net/~honeyg/progstone/
http:/
One of the best ideas that I ever encountered was that the length of variable names should be proportional to the size of their scope. So, one the one hand, this is OK:
for (int i=0; i
(assuming that the "..." doesn't contain any braces), but function/method arguments should be longer, like "name" and "parts" in this:
int createWidget(string name, billOfMaterials parts) {...}
and globally-visible items (like the class and method names above) get the longest names.
Nothing for 6-digit uids?
If your team is not documenting the architecture and code libraries in a programmers manual they are not being professionally managed (Danger Will Robinson). Also, coding teams should either work to a given set of coding standards and guidelines (it's up to your team what they are) to ensure and enhance a style within the architecture that is easy for any maintainer to work with, and for future teams to enhance and develop, which itself should also be a formal document.
Many programmers do not like working with such disciplines, but I am sure the more experienced ones out there actually agree, that if projects start with such disciplines, the chances of project success and deliverables if much more enhanced, and the ease of development between version is also better managed. Without such disciplines, each version becomes more and more difficult to manage. You can have fun working with such disciplines, the experience of writing better, more clearly defined quality code is very rewarding in itself.
And as stated here already, say why you did something, not what the code does.
One of the best ideas that I ever encountered was that the length of variable names should be proportional to the size of their scope. So, one the one hand, this is OK: ... }
for (int i=0; i<size; ++i) {
(assuming that the "..." doesn't contain any braces), but function/method arguments should be longer, like this:
int createWidget(string name, billOfMaterials parts) {...}
and globally-visible items (like the class and function/method names above) get the longest names.
Nothing for 6-digit uids?
In the end, you want something clear and concise. But describing how to get there is tough.
Ok, it's a (little bit) too much effort for
...
the 'average' programmer, but I've seen the
benefits:
- Before the function/method, describe the purpose of the function and it's arguments )
// this function returns 1 divided by the squareroot of (A + B)
double invsqrtAB(double A, double B) {
// 1.first add A and B
// 2.then take the square root of it
// 3.and then divide 1 by the above result
// add arguments (1)
double C = A + B;
// squareroot (2)
C = sqrt(C);
// final step (3)
C = 1 / C;
// we're done
return C;
}
It really helps if you have large functions and if a thirds party has to add functionality, bugfix or just understand/review your code!
Especially after a long time
To quote our good friend Martin Fowler (in reference to Smelly Code):
"Comments are a sweet smell in code. But sometimes they are used as a deoderant, intented to mask a foul smell. If you need comments to explain a section of code, its time to Refactor".
Comments will not solve your software maintainance problems. Refactoring will. If you havn't read Martins book, then drop everything and read it. Refactoring, as well as the Gang of Four book, are the most influential books on Software Engineering.
Revolution = Evolution
Well commented code can be a godsend but at the same time I find it difficult do debug code that is littered with un-needed comments:
//print the data
printf("The data is: %s", data);
The book can be summed up in one sentence:
"The process *is* the product"
I have been trapped in a company that thought that adding process -- even the wrong process -- was the right way to manage.
The problem with the process is that it's anti-innovative; not "non-innovative": "anti-innovative".
In a recent article in Technology Review (available for free viewing, online) Clayton Christianson said it best:
"Sony, for example, was history's most successful disruptor. Between 1950 and 1980 it introduced 12 bona fide disruptive technologies that created exciting new markets and ultimately dethroned industry leaders--everything from radios and televisions to VCRs and the Walkman. Between 1980 and 1997, however, the company did not introduce a single disruptive innovation. Sony continued to produce sustaining innovations in its product businesses, of course. But even the new businesses that it created with its PlayStation and Vaio notebook computer were great but late entries into already established markets.
What drove Sony's shift from a disruptive to a sustaining innovation strategy? Prior to 1980, all new product launch decisions were made by cofounder Akio Morita and a trusted team of associates. They never did market research, believing that if markets did not exist they could not be analyzed. Their process for assessing new opportunities relied on personal intuition. In the 1980s Morita withdrew from active management in order to be more involved in Japanese politics. The company consequently began hiring marketing and product-planning professionals who brought with them data-intensive, analytical processes of doing market research. Those processes were very good at uncovering unmet customer needs in existing product markets. But making the intuitive bets required to launch disruptive businesses became impossible."
Adding process is not the answer, unless that process is necessary and utilitarian.
"I only work with Perl" ... "I've never had to deal with 'obfuscated' code"
Functions should have their arguments documented-- what they mean and what they do, and their return values documented. That is sufficient.
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.
LedgerSMB: Open source Accounting/ERP
cWordVar or sWord_Var
my point was that underscores_between_words_is_easier_to readThanCamelCapsIs, regardless of length of names. And extra capitalization is annoying. (also, I hope sWord_Var is not in a game where it could be misread to apply to a weapon).
...and this lie crawls out of its mouth: 'I, the state, am the people.'
And calling for coding standards including standardized comments? I've seen a lot of attempts at this in my 22 yrs in the business and all of them are tedious when detailed enough to generalize comments. They tend to lower code to a LCD that everyone either agrees on or just got tired of the entire process. They don't generally do anything for real code quality (which isn't a matter of standards) or for real readability either all too often. As a geek I am much more interested in how to design and write code more beautifully and powerfully. I am hardly at all interested in 'coding standards'.
I agree with some of the suggestions which recommend adopting a team coding standard. However, to get started quickly I'd also recommend grabbing publicly available coding standards from successful teams who are already well-established (and modifying them as necessary for your own needs). For example, my friends who worked on maintaining LAM (formerly the LSC at the University of Notre Dame, they are now in the CS department at Indiana University) had an excellent coding standard that included rules for commenting code ("The LSC Coding Standard"). I'm not sure if the document outlining their standard is publicly available, but you could certainly contact them (or any other successful coding teams you know of) and ask them for a copy. I haven't worked much in industry, but most of the people I know in the academic/research software development groups seem likely to be willing to share already-written documents outlining the nitty-gritties of their coding standards. Also, for more good advice on the process of good software development, I highly recommend a book called the Pragmatic Programmer.
... "this code is bizzarre, and magicians never reveal their secrets"
While not dedicated to coding style alone it is a good read. It is fairly short (~260 pages), it is well written, and it covers a lot of topics.
If you want more details:
Title: The Practice of Programming
By: Brian W. Kernighan and Rob Pike
ISBN: 0-201-61586-X
Printed Price: $24.95 US
Just my little pet gripe about commenting:
// add one to the variable
Tell me why you are doing something, not just what you are doing
Just a little example:
intVariable += 1
Well duh! I can see that. But why are you adding one to the variable. Any fool can see that we are adding one to the variable, that is the only thing that doesn't need commenting. What I want to know is why you are adding one, is it a counter, some sort of index?
Yes, sometimes an explaination of what you are doing is required as well but the big question is why. 'What' can usually be figured out without too much hassle but 'why' is what we all need to know.
just my 4 cents (I'm dealing in $AUS so I gotta double my 2 cents)
"She's a West Texas girl, just like me" - G.W Bush Iraqis
Why the heck would you run nm on executables? What's that supposed to tell you? Especially C++ code, you aren't going to learn much.
The "How to write Unmaintainable Code" article on the web is an excellent resource for documentation - much as "Web Pages that Suck is an excellent guide for web designers.
Your organisation - even if it's just 1 man and a dog - should already have a style guide in place. Don't have one? Well then it's easy, there are plenty of good ones on the Net, for Java, C++,Lisp,MATLAB, Ada and many others.
A good list of C and C++ styleguides is here. Just pick one. The important thing is to make sure everyone uses the same one, exactly which one is more a religious issue than anything else. That's an over-simplification, some really are better than others, but at least all the ones on that list have been tried, tested and peer-reviewed.
As for my own opinions, a few issues
- Make variable names meaningful. If you do this, then most of your comments will be metadata, e.g why you did something, and who and when a change was made, rather than what is being done. If you're doing something tricky or unusual, then having a pseudocode preamble can be worthwhile.
- If you can, try to use a relatively high-level language like Ada rather than a low-level one like C. But this is almost never under your control. The Javadoc auto-documentation tool is one of the biggest plusses that Java has over other languages - so if programming in Java, Use It!!
One final thing: your teachers should be castigated for not teaching you this already. For my sins, I've been a CS teacher at ADFA and coding style was always worth Far more marks than merely getting a chunk of code to do something right. Hacking a Kludge to do some trivial mickey-mouse stuff is far easier than professional programming, any 9-year-old hacker with VB can do that. But to make a diamond-hard industrial-strength software component that people's lives can depend upon, that can be modified easily and retain its integrity throughout its lifecycle, that's "non-trivial".Zoe Brain - Rocket Scientist
Writing well documented code is an easy four step process.
Step 1: Write undocumented code.
Step 2: Place code aside for 6 months.
Step 3: Look at your code again and document which parts of it you do not understand.
Step 4: Study the parts of the code you do not understand until you remember what you did, then document that.
You now have well documented code.
A beowulf cluster of comments?
I thought all production oriented linkers removed the name referrances when you do a non-debug link.
You *DO* know that you can use HTML tags such as
- boldface
- italics
-
- bulleted
- lists
to emphasize parts of your comments, don't you?The HP75 (yeah, I'm damn old) had some interesting comments, though not always in the source code...
... (wiping a tear from her eye) I guess a programmer must do
x t
SCENE: Fade to a small cottage in the sheep country of New Zealand.
Roo-man is standing in the doorway. His dark masculine hands, callused
with long hours at the terminal, grip the shoulders of a young, raven
haired woman.
"Wendy, my dearest, you must understand we face difficult times.
Times through which only the resourceful, the methodical, the
dedicated will accomplish the tasks that lay ahead. I do not do these
things lightly. We may have to give a little against the foe of
piece-meal programming in order to gain on the other fronts facing
limited space and slow processing speed. Yes, Wendy, this is a
calculated risk, but it's a risk that's got to be taken!"
"Oh, Roo-man, I never doubted that you had the best intentions. I
guess
what he must do."
Roo-man enfolds her in his arms, briefly forgetting the heavy
responsibilities that have been laid upon him. Pausing, he holds her
at a distance as if memorizing every feature. Brushing the hair from
her eyes he smiles, then briskly turning hops between space and time,
reassured that the one who means most believes in what he is about to
do.
http://www.hpcalc.org/hp48/docs/humor/rooman3.t
http://www.hpmuseum.org/hp75.htm
Ideally you'll all be using the same development tool.
If lucky enough to start a project from scratch, agree with other developers on a coding style and use a code formatting tool to enforce those standards.
e.g. hello () {
// stuff here
}
v.s. hello ()
{
// stuff here
}
One that adds missing Javadoc comments would be handy to.
That way classes remain easy to read.
But do this early, otherwise you get CVS diffs where formatting has changed everywhere!
If you want one that covers those culprits, read Rapid Development by the same author - it talks about the management end of software engineering. Code Complete is meant to cover the programming end.
Coments shoud, from what I remember from my CS courses.
a) Describe in detail what the function does, or what the variable(s) store
b) Describe the preconditions of the function (what has to happen for the function to be called)
c) Describe the post conditions (what the end result of the function is (what does it return and where does it send the data)
T Money
World Domination with a plastic spoon since 1984
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.
:-) (now don't get your panties in a bunch, I'm just yanking your chain)
Contrast this with changing the code, which can safely be done willy-nilly. Thank you for saving us from random code changes by adding blocks of unverifiable natural language which may have a vaguely similar meaning to anyone other than the original author.
But if the objective is to mitigate the risk of change, might I suggest trying unit testing?
Test Infected
I actually don't worry about the potential adverse side effects in some distant section that might result from improving this section. If it passes the tests, it is right. If it is wrong, it will not pass the tests. If it passes the tests and a bug is later found, it indicates an opportunity for improvement of the unit tests. Enhance the unit tests to reflect the newly discovered requirement, then do the minimal improvements to the code necessary to pass the improved unit test.
I will make you two promises: 1. It will feel extremely unnatural at first. 2. If you really commit to it in version n, you will experience less bugs in version n+1. Unfortunately, it is impossible to perceive a bug that never exists, so you will have to have a fairly solid feel for how many bugs to anticipate to fully appreciate the improvement.
As anecdotal evidence; when I build up a new package, I start with the unit tests for the smallest components first, and gradually build my way up. At the end, I start wiring all the subcomponents together. It is not uncommon for me to spend two weeks developing a collection of classes, and less than an hour debugging them in the final integration.
Stop-Prism.org: Opt Out of Surveillance
Someone may have already pointed this out, but C++ variables are usually cryptic, as are C variables. It's just kinda the nature of the language. Comments shouldn't be cryptic, though.
oh boy, where to begin... forget the example, may be stupid, so what, the point is that it is ridiculous to put a dozen fucken logic statements together with a little comment above stating what the mess should mean.
) i on))
this is usually with an abundance of operators and a sparsity of parenthesis.
i spend every day untangling stuff into *short lines* and i feel good.
~~~~
` ** apply promotion filters **
` selection sequence filter
$version_needed:=$valid_version_code
If ((Records in set("Selection_Filter_Set")>0) & $version_needed)
$version_needed:=$version_needed & (Is in set("Selection_Filter_Set"))
End if
` usages filter (cute hack? automatics!)
If ((Size of array($usages_array)>0) & $version_needed)
$usage:=[Promotion_Selection]Usage
If (Substring($usage;1;1)="A")
$usage:="A##"
End if
$version_needed:=$version_needed & (Find in array($usages_array;$usage)>0)
End if
` revisions filter
If (($filter_from_revision>0) & $version_needed)
$version_needed:=$version_needed & ([Promotion_Selection]Revision>$filter_from_rev ision)
End if
` date filter
If (($filter_since_date#!00.00.00!) & $version_needed)
$version_needed:=$version_needed & ([Promotion_Selection]Date_Changed>$filter_sinc e_date)
End if
` ** apply version filters **
` latin version filter
If ($spanish_version & $version_needed)
$version_needed:=$version_needed & $include_latin_versions
End if
` cycle-feature filter
$cycle_feature:=([Promotion_Selection]Usage="FEA"
If ($cycle_feature & $omit_cycle_features & $version_needed)
$version:=Substring($version;1;1)+"1"
End if
` written text filter
QUERY([Copy];[Copy]Pull_Version=($selection+$vers
$copy_okay:=((Records in selection([Copy])=1) & ([Copy]Proof_Status="OK"))
If ($copy_okay & $version_needed)
$version_needed:=$version_needed & (Not($omit_written_versions))
End if
Knuth may be brilliant but his code wouldn't even earn him a call-back interview in the company I work for.
comments are nothing more than that which makes a good reading short story (or book). It follows well and if you leave them out, your readers imagination may not only distort your story, but also "sharply" hurt them in the long run, leaving you with terribly bad reviews. I am a commenting (as well as a formatting) freak.
Just read any book by Walter Rudin. There you will find the proper amount of comments.
Intentionally hilarious, but as it says, "checking for unmaintainable design patterns is a rapid way to defend against malicious or inadvertent sloppiness."
Thanks a lot! Eventually, I'll go buy the O'Reilly Emacs book. :)
-Chris
Back in the day we got in the Win 3 SDK. In a C example, to get out of 3 or 4 nested loops if there was an error condition there was a "goto wearefucked;" with the matching ":wearefucked;" at the end of the function.
Of course by the next version Microsoft had started working with IBM more and the goto had been changed.
there was an article4 /01/15522 25 on Newsforge a little while back that offered some sensible advice
http://newsforge.com/article.pl?sid=02/0
"I deny nothing, but doubt everything." Lord Byron
I haven't had time to read through this massive reply list, but I'll just throw my own 2 cents in...
I've found that variable names are important. I make a point of making concise and clear variable names that describe that is happenening, i.e. HitCount rather than FuckingVarCounter. I use scope names from Hungarian(g_, m_) for global and classes, but avoid prefixing types(i, l, f, etc.), mainly because if a var type is cahnged later it gets really irritating. Of course, Replace All is useful too...In any case, I feel that the name of a variable should also make it's type obvious(e.g. NumSheep should be an integer).
As for comments, I use them to explain algos that are not really basic(not like a simple loop) and generally explain _why_ something is being done. I use newlines to divide code inside functions into logical blocks, rather than cutting it into senselessly multiple functions.
Been coding since '68. After long bitter experience, I now strip all comments out of code before I read the code. I have found that this speeds up debugging/trouble shooting. You don't get suckered in with someones past dreams about what the code should do, instead you can deal with what the code really does. Learn to read code.
I use them every day. Some of the code I deal with performs complicated mathematical algorithms. The functions run to 100+ lines. The algorithm is a compete entity in itself. It has no logical subparts. It does not decompose into meaningful steps. It just does a whole bunch 'o maths. Are you suggesting that I should refactor this code into separate parts at some arbitrary points just to keep the code shorter than 20 lines per function?
All the evidence I've ever seen says that not only do longer functions not harm readability (up to a limit of around 150-200 lines, at least), arbitrary decomposition such as you advocate does harm readability, because it forces the reader to jump around for no good reason.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
And don't tell me to think before coding. If you are going to write a heap-sort program, of course you should have a clear idea on the algorithm, but it is just HARD not to make a few mistakes (like n/2 vs. (n+1)/2) in the code, especially when implementing such an algorithm for the first time.
I changed to Dvorak a while back, and my experience was that it did not noticably increase typing speed. It
- did
however, significantly reduce the wrist and finger strain I had been suffering...