Related
is there any way to overload the "dot"-operator "."
We would like to use our old code base while rewriting the ORM layer. So we had the idea to wrap the objects and add some new semantic to the member selection operator "."
We found a several sites discussing that, including here on SO, all say in theory it would be fine but current C++ standard does not allow it.
Maybe there is already a compiler which does it?
EDIT
thanks for your quick answers; We see it might be hard if not impossible to find such a compiler. Any further hints are appreciated. All your posted resources we already had read...
Briefly what we want to achieve: The wrapper does not have any own members, it just should provide the former real object in another way. It would be very convenient to implement our new layer for reasons of backward compatibility - we could avoid to modify the legacy client code in about >4000 occurrences.
If you have any other idea how to proceed in another way, please tell. Will this limit be still there in C++11 ?
EDIT 2
Not sure yet, I am going to report what we do.
You can't overload the dot operator, and there is no c++ compiler that supports this property. Check this link from wikipedia which explains operator overloading in C++ in more detail. http://en.wikipedia.org/wiki/C%2B%2B_operators
Me and a colleague are starting a new project and attempting to take full advantage of TDD. We're still figuring out all the concepts around unit testing and are thus far basing them primarily on other examples.
My colleague recently brought into question the point of the NUnit syntax helpers and I'm struggling to explain their benefit (since I don't really understand it myself other than my gut says they're good!). Here is an example assertion:
Assert.That(product.IsValid(), Is.False);
To me this makes complete sense, we're saying we expect the value of product.IsValid() to be false. My colleague on the other hand would prefer us to simply write:
Assert.That(!product.IsValid());
He says to him this makes more sense and he can read it easier.
So far the only thing we can agree on is that you are likely to get more helpful output when the test is failing from the former, but I think there must be a better explanation. I've looked up some information on the syntax helpers (http://nunit.com/blogs/?p=44) and they make sense, but I don't fully understand the concept of constraints other than they 'feel' right.
I wonder if someone could explain why we use the concept of constraints, and why they improve the unit test examples above?
Thanks.
I think it's mostly to do with the pure English reading of the statement.
The first reads
Assert that product is valid is false
The second reads
Assert that not product is valid
I personally find the first easier to process. I think it's all down to preference really. Some of the extension methods out there are interesting though that let you do you assertions like this:
product.IsValid().IsFalse();
I can see your version being better than your colleagues. However, I'd still be at least as comfortable with:
Assert.IsFalse(product.IsValid());
If you can convince me that the Assert.That syntax has an objective benefit over the above, I'd be very interested :) It may well just force of habit, but I can very easily read the "What kind of assertion are we making? Now what are we asserting it about?" style.
It's all sugar. Internally they're converted to constraints.
From Pragmatic Unit Testing, pg 37:
"NUnit 2.4 introduced a new style of assertions that are a little less procedural and allow for a more object oriented underlying implementation.
...
For instance:
Assert.That(actual, Is.EqualTo(expected));
Converts to:
Assert.That(actual, new EqualConstraint(expected));"
Using constraints also allows you to inherit from Constraint and create your own custom constraint(s) while keeping a consistent syntax.
I don't like Assert.That, specifically the fact that its most common scenario (comparing two objects' equality) is measurably worse than the 'classic' Assert.AreEqual() syntax.
On the other hand, I super love the MSpec NUnit extensions. I recommend you check them out (or look at the SpecUnit extensions, or NBehave extensions, or NBehaveSpec*Unit extensions, I think they're all the same).
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
How to keep the source code well documented/commented? Is there a tool to generate a skeleton for comments on the Unix platform for C++?
In general, how many lines of comments is recommended for a file with around 100 lines of code?
Generally, it's best to let the code itself explain what it does, whereas the comments are there to describe why it's like that. There is no number to stick to. If your 100 lines speak for themselves, don't comment at all or just provide a summary at the beginning. If there is some knowledge involved that's beyond what the code does, explain it in a comment.
If you're code is too complicated to explain itself, then that may be a reason to refactor.
This way, when you change the implementation you don't need to change the comments as well, as your comments do not duplicate the code. Since the reasons for the design seldom change it's safe to document them in comments for clarity.
Personally I think skeleton comments are a horrible, horrible idea. I understand that sometimes it's nice to save couple of keystrokes and perhaps get argument signatures in comment... but resulting n+1 empty useless comments (when editor has added boilerplates and coder has left them as is) are just more irritating.
I do think comments are needed, at any rate -- if only code one writes is too trivial to ned explanation, chances are code in question is useless (i.e. could have been automated and needn't be hand-written). I tend to comment my code reasonably well because I have learnt that usually I need it myself first. That others can use them is just an added bonus.
In general, how many lines of comments is recommended for a file with around 100 lines of code?
Enough to make your intent clear and to explain any unfamiliar idioms used. There's no rule of thumb, because no two 100 lines of code are the same.
For example, in C#, a property can be given setters and getters like this:
public int ID { get; set; }
Now I hadn't even seen any C# until I joined StackOverflow two weeks ago, but that needs no comment even for me. Commenting that with
// accessor and setter for ID property
would just be noise. Similarly,
for( int i = m ; i < n; ++i) { // "loop from m to n" is a pointless comment
char* p = getP() ; // set p to getP, pure noise.
if( p ) // if p does not eqaul null, pure noise
int a &= 0x3; // a is bitwise or'd with 0x303, pure noise
// mask off all but two least significant bits,
//less noisy but still bad
// get remainder of a / 4, finally a useful comment
Again, any competent coder can read the code to see what it's doing. Any coder with basic experience knows that if( p ) is a common idiom for if( p != 0), which doesn't need explaining. But no one can read your intent unless you comment it.
Comment what you're trying to do, your reason for doing it, not what the code is plainly doing.
On edit: you'll note that after 11 days, no one has commented on intentional error in one of my example comments. That just underscores that that comment is pure noise.
I think this question has a lot of good relevant answers for a similar question: Self-documenting code
As for tools for creating comments, it depends on the editor you're using and the platform. Visual studio automatically creates space for comments, at least it does for C# sometimes. There are also tools that use comments to generate documentation. As for lines counts, I think that's irrelevant. Be as concise and clear as possible.
I think a good guideline is to comment every class and method with a general description of what each is for, especially if you are using an HTML documentation generation tool. Other than that, I try to keep comments to a minimum - only comment code that could potentially be confusing, or require interpretation of intent. Try to write your code in a way that doesn't require comments.
I don't think there is really a metric that you can apply to comments/lines of code, it just depends on the code.
My personal ideal is to write enough commentary so that reading just the comments explains how and why a function is intended to be used. How it works, should usually come out from well chosen variable names and clear implementation.
One way to achieve that, at least on the comment side, is to use a tool such as Doxygen from the beginning. Start coding each new function by writing the comment describing what it is for and how it should be used.
Get Doxygen configured well, have document generation included as a build step, and read the resulting documentation.
The only comment template that might be helpful would be one that sketches in the barest beginning of the Doxygen comment block, but even that might be too much. You want the generated documentation to explain what is important without cluttering it with worthless placeholder text that will never get rewritten.
This is a subject which can be taken to extremes (like many things these days). Enforcing a strong policy sometimes can risk devaluing the exercise (i.e. comments for comment's sake) most of the time, IMHO.
Sometimes an overreaching policy makes sense (e.g. "all public functions must have comment blocks") with exceptions - why bother for generated code?
Commenting should come naturally - should compliment readble code alongside meaningful variable, property and function names (etc).
I don't think there is a useful or accurate measurement of X comments per Y lines of code. You will likely get a good sense of balance through peer reviews (e.g. "this code here should have a comment explaining it's purpose").
I'm not sure about auto-comment tools for C/C++ but the .Net equivalent would have to be GhostDoc. Again, these tools only help define a comment structure - meaning still needs to be added by a developer, or someone who has to interpret the point of the code or design.
Commenting code is essential if your auto generating your documentation (we use doxygen). Otherwise it's best to keep it to a minimum.
We use a skeleton for every method in the .cpp file.
//**************************************************************************************************
//
/// #brief
/// #details
/// #param
/// #return
/// #sa
//
//**************************************************************************************************
but this is purely due to our documentation needs
The rules I try to follow:
write code that is auto-documented: nice and clear variable names,
resist the temptation of clever hacks, etc. This advice depends a
lot on the programming language you use: it is is much easier to
follow with Python than with C.
comment at the beginning to guide the reader so that they know
immediately what they are to expect.
comment what is not obvious from the code. If you had trouble
writing a piece of code, it may mean it desserves a comment.
the API of a library is a special case: it requires
documentation (and to put it in the code is often a good idea,
especially with tools like Doxygen). Just do
not confuse this documentation intended for users with the one
which will be useful for the maintainers of the library.
comment what cannot be in the code, such as policy requirments that
explain why things are the way they are.
comment background information such a the reference to a scientific
article which describes the clever algorithm you use, or the RFC
standardizing the network protocol you implement.
comment the hacks! Everyone is sometimes forced to use hacks or
workarounds but be nice for the future maintainer, comment it. Read
"Technical debt".
And don't comment the rest. Quantitative rules like "20 % of the lines
must be comments" are plainly stupid and clearly intended only for
PHBs.
I'm not aware of any tool but I feel it's always good to have some comments in the code if it is to be maintained by someone else in the future. At least, it's good to have header blocks for classes and methods detailing what the class is meant for and what the method does. But yes, it is good to keep the comments as minimal as possible.
I prefer to use comments to explain
what a class\function is intended to do,
what it is not supposed to do,
any assumptions I make that the users of the class\function should adhere to.
For the users of vi editor the following plug-in is very helpful. We can define templates for class comments, function comments etc.
csupport plug in
There are no good rules in terms of comment/code ratios. It totally depends on the complexity of your code.
I do follow one (and only one) rule with respect to comments (I like to stay flexible).
The code show how things are done, the comments show what is done.
Some code doesn't need comments at all, due to it's obviousness: this can often be achieved by use of good variable names. Mostly, I'll comment a function then comment major blocks withing the function.
I consider this bad:
// Process list by running through the whole list,
// processing each node within the list.
//
void processList (tNode *s) {
while (s != NULL) { // Run until reached end of list.
processNode (s); // Process the node.
s = s->nxt; // Move to next node.
}
}
since all you're doing there is writing the code thrice. I would prefer something like:
// Process list (or rest of list if you pass a non-start node).
//
void processList (tNode *currentNode) {
// Run through the list, processing each node.
while (currentNode != NULL) {
processNode (currentNode);
currentNode = currentNode->nextNode;
}
}
You guys may argue about but i realy believe in it:
Usually , You don't have to write comments. Simply as that. The code has to be written in such way that is explain itself , if it doesn't explain itself and you have to write comments , then something is wrong.
There are however some exceptional cases:
You have to write something that is VERY cryptic to gain performence. So here you may need to write some explanation.
You provide a library to some other group/company , It is better you document its API.
There are too many novice programemers in your organization.
I wouldn't be so rude to say that comments are excuse for badly programmed code like some people above, nor to say you don't need them.
It also depends on your editor and how do you like to see your code in it, and how would you like others to do that.
For instance, I like to create regions in C#. Regions are named collapsable areas of code, in some way commented code containers. That way, when I look at the editor, I actually look at pseudo code.
#region Connect to the database
// ....
#endregion
#region Prepare tables
#region Cache tables ...
#endregion
#region Fix column names ...
#endregion
#endregion
This kind of code is more readable then anything else I know but ofcourse, it needs editor supporing custom folding with names. (like Visual Studio editor, VIM... ). Somebody will say that you can achieve the similar if you put regions into procedures but first, you can't always do that, second, you have to jump to the procedure to see its code. If you simply set hotkies to open/collapse the region you can quickly see the code in it while scrolling and reading text and generally quickly move over the hierarchy of regions.
About line comments, it would be good to write code that autodocuments itself, but unfortunatelly, this can't be said in generall. This ofcourse depends on projects, its domain and its complexity.
As a last note, I fully suggest in-code documentation via portable and language indepent tool, like for instance NaturalDocs that can be made to work with any language around with natural syntax that doesn't include XML or any kind of special formating (hence the name) plus it doesn't need to be installed more then once.
And if there is a guy that don't like comments, he can always remove them using some simple tool. I even integrated such tool in my editor and comments are gone via simple menu click. So, comments can't harm the code in any way that can't be fixed very fast.
I say that generally comments are a bad smell. But inline code documentation is great. I've elaborated more on the subject over at robowiki.net:
Why Comments are Bad
I concur with everyone about self-documenting code. And I also agree about the need for special comments when it comes to documentation generation. A short comment at the top of each method/class is useful, especially if your IDE can use it for tooltips in code completion (like Visual Studio).
Another reason for comments that I don't see mentioned here is in type-unsafe languages like JavaScript or PHP. You can specify data types that way, although hungarian notation can help there as well (one of the rare cases for using it properly, I think).
Also, tools like PHPLint can use some special type-related comments to check your code for type-safety.
There are no metrics you can sensibly use for comments. You should never say x lines of code must have y comments, because then you will end up with silly useless comments that simply restate code, and these will degrade the quality of your code.
100 lines of code should have as few comments as possible.
Personally, having used them in the past, I'd not use things like doxygen to document internal code to the extent of every function and every parameter needing tagged descriptions because with well factored code you have many functions and with good names, most often these tagged descriptions don't say any more than the parameter name itself.
My opinion - comments in source code is evil. Code should be self documented. Developers usually forget about reading and updating them.
As sad Martin Fowler: "if you need comment for lines block - just make new function" (this not quote - this phrase as I remember it).
It will be better to keep separated documentation for utility modules, basic principles of your project, organization of libraries, some algorithms and design ideas.
Almost forget: I was used code comments once. It was MFC/COM - project and I leave links from MSDN howto articles near non-trivial solutions/workarounds.
100 lines of source code - should be understandable if not - it should be separated or reorganized on few functions - which will be more understandable.
Is there a tool to generate a skeleton
for comments on the Unix platform for
C++?
Vim have plugins for inserting doxygen comments template, if you really need this.
Source code should always be documented where needed. People have argued for what and what not to document. However I wanted to attribute with one more note.
Let's say I have implemented a method that return a/b
So as the programmer I am a great citizen, and I will hint the user what to expect.
/**
* Will return 0 if b is 0, to prevent the world from exploding.
*/
float divide(float a, float b) {
if (b == 0) return 0;
return a/b;
}
I know, this is pretty obvious that nobody would ever create such a method. But this can be reflected to other issues, where users of an API can't figure out what a function expects.
It is a university task in my group to write a compiler of C-like language. Of course I am going to implement a small part of our beloved C++.
The exact task is absolutely stupid, and the lecturer told us it need to be self-compilable (should be able to compile itself) - so, he meant not to use libraries such as Boost and STL. He also does not want us to use templates because it is hard to implement.
The question is - is it real for me, as I`m going to write this project on my own, with the deadline at the end of May - the middle of June (this year), to implement not only templates, but also nested classes, namespaces, virtual functions tables at the level of syntax analysis?
PS I am not noobie in C++
Stick to doing a C compiler.
Believe me, it's hard enough work building a decent C compiler, especially if its expected to compile itself. Trying to support all the C++ features like nested classes and templates will drive you insane. Perhaps a group could do it, but on your own, I think a C compiler is more than enough to do.
If you are dead set on this, at least implement a C-like language first (so you have something to hand in). Then focus on showing off.
"The exact task is absolutely stupid" - I don't think you're in a position to make that judgment fairly. Better to drop that view.
"I`m going to write this project on my own" - you said it's a group project. Are you saying that your group doesn't want to go along with your view that it should morph into C++, so you're taking off and working on your own? There's another bit I'd recommend changing.
It doesn't matter how knowledgable you are about C++. Your ability with grammars, parsers, lexers, ASTs, and code generation seems far more germane.
Without knowing more about you or the assignment, I'd say that you'd be doing well to have the original assignment done by the end of May. That's three months away. Stick to the assignment. It might surprise you with its difficulty.
If you finish early, and fulfill your obligation to your team, I'd say you should feel free to modify what's produced to add C++ features.
I'll bet it took Bjarne Stroustrup more than three months to add objects to C. Don't overestimate yourself or underestimate the original assignment.
No problem. And while you're at it, why not implement an operating system for it to run on too.
Follow the assignment. Write a compiler for a C-like language!
What I'd do is select a subset of C. Remove floating-point datatypes and every other feature that isn't necessary in building your compiler.
Writing a C compiler is a lot of work. You won't be able to do that in a couple of months.
Writing a C++ compiler is downright insane. You wouldn't be able to do that in 5 years.
I will like to stress a few points already mentioned and give a few references.
1) STICK TO THE 1989 ANSI C STANDARD WITH NO OPTIMIZATION.
2) Don't worry, with proper guidance, good organization and a fair amount of hard work this is doable.
3) Read the The C Programming Language cover to cover.
4) Understand important concepts of compiler development from the Dragon Book.
5) Take a look at lcc both the code as well as the book.
6) Take a look at Lex and Yacc (or Flex and Bison)
7) Writing a C compiler (up to the point it can self compile) is a rite of passage ritual among programmers. Enjoy it.
For a class project, I think that requiring the compiler to be able to compile itself is a bit much to ask. I assume that this is what was meant by stupid in the question. It means that you need to figure out in advance exactly how much of C you are going to implement, and stick to that in building the compiler. So, building a symbol table using primitives rather than just using an STL map. This might be useful for a data structure course, but misses the point for a compiler course. It should be about understanding the issues involved with the compiler, and chosing which data structures to use, not coding the data structures.
Building a compiler is a wonderful way to really understand what happens to your code once the compiler get a hold of it. What is the target language? When I took compilers, it took 3 of us all semester to build a compiler to go from sorta-pascal to assembly. Its not a trivial task. Its one of those things that seems simple at first, but the more you get into it, the more complicated things get.
You should be able to complete c-like language within the time frame. Assuming you are taking more than 1 course, that is exactly what you might be able to do in time. C++ is also doable but with a lot more extra hours to put it. Expecing to do c++ templates/virtual functions is overexpecting yourself and you might fail in the assignment all together. So it's better stick with a c subset compiler and finish it in time. You should also consider the time it takes for QA. If you want to be thorough QA itself will also take good time.
Namespaces or nested clases, either virtual functions are at syntax level quite simple, its just one or two more rules to parser. It is much more complicated at higher levels, at deciding, which function / class choose (name shadowing, ambiguous names between namespaces, etc.), or when compiling to bytecode/running AST. So - you may be able to write these, but if isn't necessary, skip it, and write just bare functional model.
If you are talking about a complete compiler, with code generation, then forget it. If you just intend to do the lexical & syntactic analysis side of things, then some form of templating may just about be doable in the time frame, depending on what compiler building tools you use.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
What guidelines do you follow to improve the general quality of your code? Many people have rules about how to write C++ code that (supposedly) make it harder to make mistakes. I've seen people insist that every if statement is followed by a brace block ({...}).
I'm interested in what guidelines other people follow, and the reasons behind them. I'm also interested in guidelines that you think are rubbish, but are commonly held. Can anyone suggest a few?
To get the ball rolling, I'll mention a few to start with:
Always use braces after every if / else statement (mentioned above). The rationale behind this is that it's not always easy to tell if a single statement is actually one statement, or a preprocessor macro that expands to more than one statement, so this code would break:
// top of file:
#define statement doSomething(); doSomethingElse
// in implementation:
if (somecondition)
doSomething();
but if you use braces then it will work as expected.
Use preprocessor macros for conditional compilation ONLY. preprocessor macros can cause all sorts of hell, since they don't allow C++ scoping rules. I've run aground many times due to preprocessor macros with common names in header files. If you're not careful you can cause all sorts of havoc!
Now over to you.
A few of my personal favorites:
Strive to write code that is const correct. You will enlist the compiler to help weed out easy to fix but sometimes painful bugs. Your code will also tell a story of what you had in mind at the time you wrote it -- valuable for newcomers or maintainers once you're gone.
Get out of the memory management business. Learn to use smart pointers: std::auto_ptr, std::tr1::shared_ptr (or boost::shared_ptr) and boost::scoped_ptr. Learn the differences between them and when to use one vs. another.
You're probably going to be using the Standard Template Library. Read the Josuttis book. Don't just stop after the first few chapters on containers thinking that you know the STL. Push through to the good stuff: algorithms and function objects.
Delete unnecessary code.
That is all.
Use and enforce a common coding style and guidelines. Rationale: Every developer on the team or in the firm is able to read the code without distractions that may occur due to different brace styles or similar.
Regularly do a full rebuild of your entire source base (i.e. do daily builds or builds after each checkin) and report any errors! Rationale: The source is almost always in a usable state, and problems are detected shortly after they are "implemented", where problem solving is cheap.
Turn on all the warnings you can stand in your compiler (gcc: -Wall is a good start but doesn't include everything so check the docs), and make them errors so you have to fix them (gcc: -Werror).
Google's style guide, mentioned in one of these answers, is pretty solid. There's some pointless stuff in it, but it's more good than bad.
Sutter and Alexandrescu wrote a decent book on this subject, called C++ Coding Standards.
Here's some general tips from lil' ole me:
Your indentation and bracketing style are both wrong. So are everyone else's. So follow the project's standards for this. Swallow your pride and setup your editor so that everything is as consistent as possible with the rest of the codebase. It's really really annoying having to read code that's indented inconsistently. That said, bracketing and indenting have nothing whatsoever to do with "improving your code." It's more about improving your ability to work with others.
Comment well. This is extremely subjective, but in general it's always good to write comments about why code works the way it does, rather than explaining what it does. Of course for complex code it's also good for programmers who may not be familiar with the algorithm or code to have an idea of what it's doing as well. Links to descriptions of the algorithms employed are very welcome.
Express logic in as straightforward a manner as possible. Ironically suggestions like "put constants on the left side of comparisons" have gone wrong here, I think. They're very popular, but for English speakers, they often break the logical flow of the program to those reading. If you can't trust yourself (or your compiler) to write equality compares correctly, then by all means use tricks like this. But you're sacrificing clarity when you do it. Also falling under this category are things like ... "Does my logic have 3 levels of indentation? Could it be simpler?" and rolling similar code into functions. Maybe even splitting up functions. It takes experience to write code that elegantly expresses the underlying logic, but it's worth working at it.
Those were pretty general. For specific tips I can't do a much better job than Sutter and Alexandrescu.
In if statements put the constant on the left i.e.
if( 12 == var )
not
if( var == 12 )
Beacause if you miss typing a '=' then it becomes assignment. In the top version the compiler says this isn't possible, in the latter it runs and the if is always true.
I use braces for if's whenever they are not on the same line.
if( a == b ) something();
if( b == d )
{
bigLongStringOfStuffThatWontFitOnASingleLineNeatly();
}
Open and close braces always get their own lines. But that is of course personal convention.
Only comment when it's only necessary to explain what the code is doing, where reading the code couldn't tell you the same.
Don't comment out code that you aren't using any more. If you want to recover old code, use your source control system. Commenting out code just makes things look messy, and makes your comments that actually are important fade into the background mess of commented code.
Use consistent formatting.
When working on legacy code employ the existing style of formatting, esp. brace style.
Get a copy of Scott Meyer's book Effective C++
Get a copy of Steve MConnell's book Code Complete.
There is also a nice C++ Style Guide used internally by Google, which includes most of the rules mentioned here.
Start to write a lot of comments -- but use that as an opportunity to refactor the code so that it's self explanatory.
ie:
for(int i=0; i<=arr.length; i++) {
arr[i].conf() //confirm that every username doesn't contain invalid characters
}
Should've been something more like
for(int i=0; i<=activeusers.length; i++) {
activeusers[i].UsernameStripInvalidChars()
}
Use tabs for indentations, but align data with spaces
This means people can decide how much to indent by changing the tab size, but also that things stay aligned (eg you might want all the '=' in a vertical line when assign values to a struct)
Allways use constants or inline functions instead of macros where posible
Never use 'using' in header files, because everything that includes that heafer will also be affected, even if the person includeing your header doesn't want all of std (for example) in their global namespace.
If something is longer than about 80 columes, break it up into multiple lines eg
if(SomeVeryLongVaribleName != LongFunction(AnotherVarible, AString) &&
BigVaribleIsValid(SomeVeryLongVaribleName))
{
DoSomething();
}
Only overload operators to make them do what the user expects, eg overloading the + and - operators for a 2dVector is fine
Always comment your code, even if its just to say what the next block is doing (eg "delete all textures that are not needed for this level"). Someone may need to work with it later, posibly after you have left and they don't want to find 1000's of lines of code with no comments to indicate whats doing what.
setup coding convention and make everyone involved follow the convention (you wouldn't want reading code that require you to figure out where is the next statement/expression because it is not indented properly)
constantly refactoring your code (get a copy of Refactoring, by Martin Fowler, pros and cons are detailed in the book)
write loosely coupled code (avoid writing comment by writing self-explanatory code, loosely coupled code tends to be easier to manage/adapt to change)
if possible, unit test your code (or if you are macho enough, TDD.)
release early, release often
avoid premature optimization (profiling helps in optimizing)
In a similar vein you might find some useful suggestions here: How do you make wrong code look wrong? What patterns do you use to avoid semantic errors?
Where you can, use pre-increment instead of post-increment.
I use PC-Lint on my C++ projects and especially like how it references existing publications such as the MISRA guidelines or Scott Meyers' "Effective C++" and "More Effective C++". Even if you are planning on writing very detailed justifications for each rule your static analysis tool checks, it is a good idea to point to established publications that your user trusts.
Here is the most important piece of advice I was given by a C++ guru, and it helped me in a few critical occasions to find bugs in my code:
Use const methods when a method is not supposed to modify the object.
Use const references and pointers in parameters when the object is not supposed to modify the object.
With these 2 rules, the compiler will tell you for free where in your code the logic is flawed!
Also, for some good techniques you might follow Google's blog "Testing on the Toilet".
Look at it six months later
make sure you indent properly
Hmm - I probably should have been a bit more specific.
I'm not so much looking for advice for myself - I'm writing a static code analysis tool (the current commercial offerings just aren't good enough for what I want), and I'm looking for ideas for plugins to highlight possible errors in the code.
Several people have mentioned things like const correctness and using smart pointers - that's the kind of think I can check for. Checking for indentation and commenting is a bit harder to do (from a programming point of view anyway).
Smart pointers have a nice way of indicating ownership very clearly. If you're a class or a function:
if you get a raw pointer, you don't own anything. You're allowed to use the pointee, courtesy of your caller, who guarantees that the pointee will stay alive longer than you.
if you get a weak_ptr, you don't own the pointee, and on top of that the pointee can disappear at any time.
if you get a shared_ptr, you own the object along with others, so you don't need to worry. Less stress, but also less control.
if you get an auto_ptr, you are the sole owner of the object. It's yours, you're the king. You have the power to destroy that object, or give it to someone else (thereby losing ownership).
I find the case for auto_ptr particularly strong: in a design, if I see an auto_ptr, I immediately know that that object is going to "wander" from one part of the system to the other.
This is at least the logic I use on my pet project. I'm not sure how many variations there can be on the topic, but until now this ruleset has served me well.