Thank you for reading this answer rather than just trying to set your own coding standards.
But beware that some people on comp.lang.c++ are very sensitive on this issue. Nearly every software engineer has, at some point, been exploited by someone who used coding standards as a "power play." Furthermore some attempts to set C++ coding standards have been made by those who didn't know what they were talking about, so the standards end up being based on what was the state-of-the-art when the standards setters were writing code. Such impositions generate an attitude of mistrust for coding standards.
Obviously anyone who asks this question wants to be trained so they don't run off on their own ignorance, but nonetheless posting a question such as this one to comp.lang.c++ tends to generate more heat than light.
For an excellent book on the subject, get Sutter and Alexandrescu, C++ Coding Standards, 220 pgs, Addison-Wesley, 2005, ISBN 0-321-11358-6. It provides 101 rules, guidelines and best practices. The authors and editors produced some solid material, then did an unusually good job of energizing the peer-review team. All of this improved the book. Buy it.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
Coding standards do not make non-OO programmers into OO programmers; only training and experience do that. If coding standards have merit, it is that they discourage the petty fragmentation that occurs when large organizations coordinate the activities of diverse groups of programmers.
But you really want more than a coding standard. The structure provided by
coding standards gives neophytes one less degree of freedom to worry about,
which is good. However, pragmatic guidelines should go well beyond
pretty-printing standards. Organizations need a consistent philosophy
of design and implementation. E.g., strong or weak typing? references or
pointers in interfaces? stream I/O or stdio? should C++ code call C code?
vice versa? how should ABCs be used? should inheritance
be used as an implementation technique or as a specification technique? what
testing strategy should be employed? inspection strategy? should interfaces
uniformly have a
What is needed is a "pseudo standard" for detailed design. I recommend a three-pronged approach to achieving this standardization: training, mentoring, and libraries. Training provides "intense instruction," mentoring allows OO to be caught rather than just taught, and high quality C++ class libraries provide "long term instruction." There is a thriving commercial market for all three kinds of "training." Advice by organizations who have been through the mill is consistent: Buy, Don't Build. Buy libraries, buy training, buy tools, buy consulting. Companies who have attempted to become a self-taught tool-shop as well as an application/system shop have found success difficult.
Few argue that coding standards are "ideal," or even "good," however they are necessary in the kind of organizations/situations described above.
The following FAQs provide some basic guidance in conventions and styles.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
No!
No matter how vast your C experience, no matter how advanced your C expertise,
being a good C programmer does not make you a good C++ programmer. Converting
from C to C++ is more than just learning the syntax and semantics of the
C++ coding standards should be tempered by C++ experts. Asking comp.lang.c++ is a start. Seek out experts who can help guide you away from pitfalls. Get training. Buy libraries and see if "good" libraries pass your coding standards. Do not set standards by yourself unless you have considerable experience in C++. Having no standard is better than having a bad standard, since improper "official" positions "harden" bad brain traces. There is a thriving market for both C++ training and libraries from which to pull expertise.
One more thing: whenever something is in demand, the potential for charlatans increases. Look before you leap. Also ask for student-reviews from past companies, since not even expertise makes someone a good communicator. Finally, select a practitioner who can teach, not a full time teacher who has a passing knowledge of the language/paradigm.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
The headers in ISO Standard C++ don't have a .h suffix. This is something the standards committee changed from former practice. The details are different between headers that existed in C and those that are specific to C++.
The C++ standard library is guaranteed to have 18 standard headers from the C
language. These headers come in two standard flavors,
The C++ standard library is also guaranteed to have 32 additional standard
headers that have no direct counterparts in C, such as
For new projects, use only the
When modifying or extending existing code that uses the old header names, you
should probably follow the practice in that code unless there's some important
reason to switch to the standard headers (such as a facility available in
standard
All of this affects the standard headers only. You're free to name your own headers anything you like; see [27.9].
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
Probably not.
People don't like typing
For example, suppose your code is counting things and you happen to use a variable or function named count. But the std library also uses the name count (it's one of the std algorithms), which could cause ambiguities.
Look, the whole point of namespaces is to prevent namespace collisions between
two independently developed piles of code. The using-directive (that's the
technical name for
If you really want to avoid typing
I personally find it's faster to type "
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
No, but as always, remember that readability is one of the most important things.
Some people feel the
Let's start with a really simple case. Suppose you need to print the result of a function call. In that case you should put the real goal (printing) at the beginning of the line, and bury the function call within the line since it's relatively incidental (this left-right thing is based on the intuitive notion that most developers think the first thing on a line is the most important thing):
Now let's extend this idea to the
All that being said, you can get pretty outrageous and unreadable code ("write
only code") using various combinations of
Personally I think the explicit if example is clearer since it emphasizes the
major thing that's going on (a decision based on the result of calling
In any event, don't forget that readability is the goal (at least it's one of
the goals). Your goal should not be to avoid certain syntactic
constructs such as
Code must be written to be read, not by the compiler, but by another human being.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
Declare near first use.
An object is initialized (constructed) the moment it is declared. If you don't have enough information to initialize an object until half way down the function, you should create it half way down the function when it can be initialized correctly. Don't initialize it to an "empty" value at the top then "assign" it later. The reason for this is runtime performance. Building an object correctly is faster than building it incorrectly and remodeling it later. Simple examples show a factor of 350% speed hit for simple classes like String. Your mileage may vary; surely the overall system degradation will be less that 350%, but there will be degradation. Unnecessary degradation.
A common retort to the above is: "we'll provide
Bottom line: Locals should be declared near their first use. Sorry that this isn't familiar to C experts, but new doesn't necessarily mean bad.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
If you already have a convention, use it. If not, consult your compiler to see what the compiler expects. Typical answers are: .cpp, .C, .cc, or .cxx (naturally the .C extension assumes a case-sensitive file system to distinguish .C from .c).
We've often used .cpp for our C++ source files, and we have also used
.C. In the latter case, when porting to case-insensitive file systems
you need to tell the compiler to treat .c files as if they were C++
source files (e.g.,
The point is that none of these filename extensions are uniformly superior to the others. We generally use whichever technique is preferred by our customer (again, these issues are dominated by business considerations, not by technical considerations).
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
If you already have a convention, use it. If not, and if you don't need your editor to distinguish between C and C++ files, simply use .h. Otherwise use whatever the editor wants, such as .H, .hh, or .hpp.
We've tended to use either .h or .hpp for our C++ header files.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
Yes, there are some practices which are generally considered dangerous. However none of these are universally "bad," since situations arise when even the worst of these is needed:
This way the "constructive" binary operators don't even need to be
friends. But it is sometimes possible to more efficiently
implement common operations (e.g., if class Fred is actually
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
Because they're evil! (Which means you should use them sparingly and with great care.)
For some reason, programmers are sloppy in their use of pointer casts. They cast this to that all over the place, then they wonder why things don't quite work right. Here's the worst thing: when the compiler gives them an error message, they add a cast to "shut the compiler up," then they "test it" to see if it seems to work. If you have a lot of pointer casts or reference casts, read on.
The compiler will often be silent when you're doing pointer-casts and/or reference casts. Pointer-casts (and reference-casts) tend to shut the compiler up. I think of them as a filter on error messages: the compiler wants to complain because it sees you're doing something stupid, but it also sees that it's not allowed to complain due to your pointer-cast, so it drops the error message into the bit-bucket. It's like putting duct tape on the compiler's mouth: it's trying to tell you something important, but you've intentionally shut it up.
A pointer-cast says to the compiler, "Stop thinking and start generating code; I'm smart, you're dumb; I'm big, you're little; I know what I'm doing so just pretend this is assembly language and generate the code." The compiler pretty much blindly generates code when you start casting you are taking control (and responsibility!) for the outcome. The compiler and the language reduce (and in some cases eliminate!) the guarantees you get as to what will happen. You're on your own.
By way of analogy, even if it's legal to juggle chainsaws, it's stupid. If something goes wrong, don't bother complaining to the chainsaw manufacturer you did something they didn't guarantee would work. You're on your own.
(To be completely fair, the language does give you some guarantees when you cast, at least in a limited subset of casts. For example, it's guaranteed to work as you'd expect if the cast happens to be from an object-pointer (a pointer to a piece of data, as opposed to a pointer-to-function or pointer-to-member) to type void* and back to the same type of object-pointer. But in a lot of cases you're on your own.)
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
It's a precedent thing. If you have a Pascal or Smalltalk background, youProbablySquashNamesTogether like this. If you have an Ada background, You_Probably_Use_A_Large_Number_Of_Underscores like this. If you have a Microsoft Windows background, you probably prefer the "Hungarian" style which means you jkuidsPrefix vndskaIdentifiers ncqWith ksldjfTheir nmdsadType. And then there are the folks with a Unix C background, who abbr evthng n use vry srt idntfr nms. (AND THE FORTRN PRGMRS LIMIT EVRYTH TO SIX LETTRS.)
So there is no universal standard. If your project team has a particular coding standard for identifier names, use it. But starting another Jihad over this will create a lot more heat than light. From a business perspective, there are only two things that matter: The code should be generally readable, and everyone on the team should use the same style.
Other than that, th difs r minr.
One more thing: don't import a coding style onto platform-specific code where it is foreign. For example, a coding style that seems natural while using a Microsoft library might look bizarre and random while using a UNIX library. Don't do it. Allow different styles for different platforms. (Just in case someone out there isn't reading carefully, don't send me email about the case of common code that is designed to be used/ported to several platforms, since that code wouldn't be platform-specific, so the above "allow different styles" guideline doesn't even apply.)
Okay, one more. Really. Don't fight the coding styles used by automatically generated code (e.g., by tools that generate code). Some people treat coding standards with religious zeal, and they try to get tools to generate code in their local style. Forget it: if a tool generates code in a different style, don't worry about it. Remember money and time?!? This whole coding standard thing was supposed to save money and time; don't turn it into a "money pit."
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
Yep, there are several.
In my opinion, the best source is Sutter and Alexandrescu, C++ Coding Standards, 220 pgs, Addison-Wesley, 2005, ISBN 0-321-11358-6. I had the privilege of serving as an advisor on that book, and the authors did a great job of energizing the pool of advisors. Everyone collaborated with an intensity and depth that I have not seen previously, and the book is better for it.
Here are a few other sources that you can use as starting points for developing your organization's coding standards (in random order) (some are out of date, some might even be bad; I'm not endorsing any; caveat emptor):
Notes:
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
Only when there is a compelling reason to do so. In other words, only when there is no "normal" syntax that will produce the same end-result.
Software decisions should be made based on money. Unless you're in an ivory tower somewhere, when you do something that increases costs, increases risks, increases time, or, in a constrained environment, increases the product's space/speed costs, you've done something "bad." In your mind you should translate all these things into money.
Because of this pragmatic, money-oriented view of software, programmers should avoid non-mainstream syntax whenever there exists a "normal" syntax that would be equivalent. If a programmer does something obscure, other programmers are confused; that costs money. These other programmers will probably introduce bugs (costs money), take longer to maintain the thing (money), have a harder time changing it (missing market windows = money), have a harder time optimizing it (in a constrained environment, somebody will have to spend money for more memory, a faster CPU, and/or a bigger battery), and perhaps have angry customers (money). It's a risk-reward thing: using abnormal syntax carries a risk, but when an equivalent, "normal" syntax would do the same thing, there is no "reward" to ameliorate that risk.
For example, the techniques used in the Obfuscated C Code Contest are, to be polite, non-normal. Yes many of them are legal, but not everything that is legal is moral. Using strange techniques will confuse other programmers. Some programmers love to "show off" how far they can push the envelope, but that puts their ego above money, and that's unprofessional. Frankly anybody who does that ought to be fired. (And if you think I'm being "mean" or "cruel," I suggest you get an attitude adjustment. Remember this: your company hired you to help it, not to hurt it, and anybody who puts their own personal ego-trips above their company's best interest simply ought to be shown the door.)
As an example of non-mainstream syntax, it's not "normal" to use the
Same goes with using
Here's another example that seems to work and may even be legal, but it's certainly not normal:
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
E-mail the author
[ C++ FAQ Lite
| Table of contents
| Subject index
| About the author
| ©
| Download your own copy ]
Revised Mar 1, 2006