Resources- Take a Look!GeneralCode Reviews. If you are interested in coding standards you may also be interested in Code Review Standards I have created atDesign StoriesOO Info SourcesDesigning Qt-Style C++ APIs- A good paper on API I design for C++. I dont agree with everything, but it is good.Unified Modeling Language (UML)OO FAQ – All You Wanted to Know About OOC++ FAQ LITEC++ Source LibrariesC++ TutorialsACE C++ LibraryCollection of Other StandardsDesign by Contract from EiffleC++ isnt Perfect, Here are Some Reasons WhyDoxygen- is a javadoc like utility that extracts comments and relevant information from your C++/C programs and generates HTML pages from it.Const Correctness- A very nice article on const correctness by Chad Loder.Abraxis Code Check- A program for checking code for coding standard violations and other problems.Book RecommendationsWhat are some good C++ books you can buy for you and your team?Koenig/Moos Accelerated C++Lippman/Moos C++ Primer 4th EditionBruce Eckels Thinking In C++Scott Meyers Effective C++Dewhursts C++ GotchasMeyers Effective STLJosuttis The C++ Standard LibraryVandevoorde/Josuttis C++ TemplatesLanger/Krefts Standard C++ IOStreams and LocalesSutters Exceptional C++Sutters More Exceptional C++ and Exceptional C++ StyleMartins Agile Software Development: Principles, Patterns, and Practices
In any case, once finalized hopefully people will play the adult and understand that this standard is reasonable, and has been found reasonable by many other programmers, and therefore is worthy of being followed even with personal reservations.
Dont put more than one class in a file. Otherwise, how will I know its there when I browse your code? Should I really need to use search to find every last thing? Cant I just poke around the code and find it? I can if you organize your code.
Theres a saying that you dont know something until you teach it. Comments are teaching what you are doing to someone else. When you are writing comments you must generate the thoughts to teach, to explain to someone else the intent behing what you are doing. Its very difficult to make a coding error when all this context is hot in your mind.
Interface and Implementation DocumentationThere are two main audiences for documentation:Cla
Aint easy – but its the way I try to run my life.
C Function NamesIn a C++ project there should be very few C functions.For C functions use the GNU convention of all lower case letters with _ as the word delimiter.JustificationIt makes C functions very different from any C++ related names.Exampleint some_bloody_function()
A name is the result of a long deep thought process about the ecology it lives in. Only a programmer who understands the system as a whole can create a name that fits with the system. If the name is appropriate everything fits together naturally, relationships are clear, meaning is derivable, and reasoning from common human expectations works as expected.
Prefixes are sometimes useful:Is- to ask a question about something. Whenever someone seesIsthey will know its a question.Get- get a value.Set- set a value.
Leaders:lead by exampledont ask anything of anyone they wouldnt do themselvesare called on to make difficult and unpopular decisionskeep the team focusedreward/support their team in whatever they dokeep/clear unnecessary crap out of the way of the teamConsensus is great. If it lasts for the project lifecycle, consider yourself blessed. Ive been on a couple projects where two engineers just blantantlydisagreed! They were always:
No All Upper Case AbbreviationsWhen confronted with a situation where you could use an all upper case abbreviation instead use an initial upper case letter followed by all lower case letters. No matter what.JustificationPeople seem to have very different intuitions when making names containing abbreviations. Its best to settle on one strategy so the names are absolutely predictable.
Class Attribute NamesAttribute names should be prepended with the character m.After the m use the same rules as for class names.m always precedes other name modifiers like p for pointer.JustificationPrepending m prevents any conflict with method names. Often your methods and attribute names will be similar, especially for accessors.Exampleclass NameOneTwo public: int VarAbc(); int ErrorNumber(); private: int mVarAbc; int mErrorNumber; String* mpName;
. If you want to make a local copy of this standard and use it as your own you are perfectly free to do so. Thats why I made it! If you find any errors or make any improvements please email me the changes so I can merge them in. I also have a programming blog at is accidently interesting at times, as is my wiki at
Make Your Code Discoverable by BrowsingProgrammers should be able to navigate your code by looking at markers in the code, namely the names and the directory structure. Nothing is more frustrating to than to have to look at pile of code and have no idea what its organizing principles are.
When youve done something ugly say so and explain how you would do it differently next time if you had more time.
Class NamesUse upper case letters as word separators, lower case for the rest of a wordFirst character in a name is upper caseNo underbars (_)JustificationOf all the different naming strategies many people found this one the best compromise.Exampleclass NameOneTwo class Name
Have a logicanl directory structure. Have directories called doc, lib, src, bin, test, pkg, install, etc and whatever, so I at least have some idea where stuff is. People use the weirdest names and lump everything together so that it it can be detangles. Clear thought is evidenced from the beginning by a directory stucture.
IntroductionStandardization is ImportantIt helps if the standard annoys everyone in some way so everyone feels they are on the same playing field. The proposal here has evolved over many projects, many companies, and literally a total of many weeks spent arguing. It is no particular persons style and is certainly open to local amendments.Good PointsWhen a project tries to adhere to common standards a few good things happen:Programmers can go into any code and figure out whats going on.New people can get up to speed quickly.People new to C++ are spared the need to develop a personal style and defend it to the death.People new to C++ are spared making the same mistakes over and over again.People make fewer mistakes in consistent environments.Programmers have a common enemy :-)Bad PointsNow the bad:The standard is usually stupid because it was made by someone who doesnt understand C++.The standard is usually stupid because its not what I do.Standards reduce creativity.Standards are unnecessary as long as people are consistent.Standards enforce too much structure.People ignore standards anyway.Standards can be used as a reason for NIH (not invented here) because the new/borrowed code wont follow the standard.DiscussionThe experience of many projects leads to the conclusion that using coding standards makes the project go smoother. Are standards necessary for success? Of course not. But they help, and we need all the help we can get! Be honest, most arguments against a particular standard come from the ego. Few decisions in a reasonable standard really can be said to be technically deficient, just matters of taste. So be flexible, control the ego a bit, and remember any project is fundamentally a team effort.
Make Names FitNames are the heart of programming. In the past people believed knowing someones true name gave them magical power over that person. If you can think up the true name for something, you give yourself and the people coming after power over the code. Dont laugh!
LeadershipI wish i had said this, but it was said by in comp.software-eng.
Method Argument NamesThe first character should be lower case.All word beginnings after the first letter should be upper case as with class names.JustificationYou can always tell which variables are passed in variables.You can use names similar to class names without conflicting with class names.Exampleclass NameOneTwo public: int StartYourEngines( Engine& rSomeEngine, Engine& rAnotherEngine);
Standards EnforcementFirst, any serious concerns about the standard should be brought up and worked out within the group. Maybe the standard is not quite appropriate for your situation. It may have overlooked important issues or maybe someone in power vehemently disagrees with certain issues 🙂
Name your files after your classes. I didnt believe this one until I saw it. Why you name a file different than the class? How I am possibly supposed to know whats in the file otherwise?
If you think your code is so clear and wonderful that nobody will have any questions then you are lying to yourself. I have never seen a large system with this wonderful self-documenting code feature. Ive seen very few small libraries are even a single class that are so wonderfully self-documented.
The general form of an attribute embedded in a comment. You can make up your own attributes and theyll be extracted.
Ill go back and forth between documenting, testing, and coding. Ill let the problem dictate what happens when as I am working my way through solving the problem. Saying testing should always come first is too simple a rule and I think misses the larger point about software development.
Use Extractable HeadersUse a document extraction system likeDoxygenwhen documenting your code.
As part of your nighlty build system have a step the generates the documentation from the source. Then index the source using a tool like Lucene. Have a front end to the search so developers can do full text searches on nightly builds and for release builds. This is a wonderfully useful feature.
define and Macro NamesPut defines and macros in all upper using _ separators.JustificationThis makes it very clear that the value is not alterable and in the case of macros, makes it clear that you are using a construct that requires care.
Pointer Variablespointers should be prepended by a p in most casesplace the*close to the pointer type not the variable nameJustificationThe idea is that the difference between a pointer, object, and a reference to an object is important for understanding the code, especially in C++ wherecan be overloaded, and casting and copy semantics are important.Pointers really are a change of type so the*belongs near the type. One reservation with this policy relates to declaring multiple variables with the same type on the same line. In C++ the pointer modifier only applies to the closest variable, not all of them, which can be very confusing, especially for newbies. You want to have one declaration per line anyway so you can document each variable.ExampleString* pName= new String; String* pName, name, address; // note, only pName is a pointer.
Enum NamesLabels All Upper Case with _ Word SeparatorsThis is the standard rule for enum labels.Exampleenum PinStateType PIN_OFF, PIN_ON ;Enums as Constants without Class ScopingSometimes people use enums as constants. When an enum is not embedded in a class make sure you use some sort of differentiating name before the label so as to prevent name clashes.Exampleenum PinStateType IfPINwas not prepended a conflict would occur as OFF and ON are probably PIN_OFF, already defined. PIN_ON ;Enums with Class ScopingJust name the enum items what you wish and always qualify with the class name: Aclass::PIN_OFF.Make a Label for an Error StateIts often useful to be able to say an enum is not in any of itsvalidstates. Make a label for an uninitialized or error state. Make it the first label if possible.Exampleenum STATE_ERR, STATE_OPEN, STATE_RUNNING, STATE_DYING;
Sometimes you need to work around a compiler problem. Document it. The problem may go away eventually.
Global ConstantsGlobal constants should be all caps with _ separators.JustificationIts tradition for global constants to named this way. You must be careful to not conflict with other globaldefines and enum labels.Exampleconst int A_GLOBAL_CONSTANT= 5;
Make Gotchas ExplicitExplicitly comment variables changed out of the normal control flow or other code likely to break during maintenance. Embedded keywords are used to point out issues and potential problems. Consider a robot will parse your comments looking for keywords, stripping them out, and making a report so people can make a special effort where needed.
Comment All Questions a Programmer May Have When Looking at Your CodeAt every point in your code think about what questions a programmer may have about the code. Its crucial you answer all those questions somehow, someway. If you dont, as the code writer, answer those questions, who will?
Global VariablesGlobal variables should be prepended with a g.JustificationIts important to know the scope of a variable.ExampleLogger gLog; Logger* gpLog;
Suffixes are sometimes useful:Max- to mean the maximum value something can have.Cnt- the current count of a running count variable.Key- key value.
Flow Chart for Project Decision Making+———+ START +———+ V YES +————+ NO +————— DOES THE —————+ DAMN THING V WORK? V +————+ +————+ +————–+ NO DONT FUCK DID YOU FUCK —–+ WITH IT WITH IT? +————+ +————–+ YES V +——+ +————-+ +—————+ HIDE NO DOES ANYONESTOPNAME=leader>
The next step in automation is to front the repository with a web server documentation can directly refer to a source file with a URL.
C++ File ExtensionsIn short: Use the.hextension for header files andfor source files.
Accepting an IdeaIts impossible.Maybe its possible, but its weak and uninteresting.It is true and I told you so.I thought of it first.How could it be otherwise.If you come to objects with a negative preconception please keep an open mind. You may still conclude objects are bunk, but theres a road you must follow to accept something different. Allow yourself to travel it for a while.6 Phases of a ProjectEnthusiasmDisillusionmentPanicA Search for the GuiltyThe Punishment of the InnocentPraise and Honor for the Non-Participants
The short answer is as long as everyone on your project agrees it doesnt really matter. The build environment should be able to invoke the right compiler for any extension. Historically speaking here have been the options:Header Files: .h, .hh, .hppSource Files: .C, .cpp, .ccHeader File Extension DiscussionUsing.hhextension is not widely popular but makes a certain kind of sense. C header files use.hfile extension and C++ based header files use.hhfile extension. The problem is if we consider a header file aninterfaceto a service then we can have a C interface to a service and C++ interface to the service in the same file. Using preprocessor directives this is possible and common. The recommendation is to stick with using the.hextension.
Method NamesUse the same rule as for class names.JustificationOf all the different naming strategies many people found this one the best compromise.Exampleclass NameOneTwo public: int DoIt(); void HandleError();
Variable Names on the Stackuse all lower case lettersuse _ as the word separator.JustificationWith this approach the scope of the variable is clear in the code.Now all variables look different and are identifiable in the code.Exampleint NameOneTwo::HandleError(int errorNumber) int error= OsErr(); Time time_of_error; ErrorProcessor error_processor; Time* p_out_of_time= 0;
means theres a Known bug here, explain it and optionally give a bug ID.
Failing willing cooperation it can be made a requirement that this standard must be followed to pass a code inspection.
The standard pointer notation is not entirely satisfactory because it doesnt look quite right, but it is consistent.
Failing that the only solution is a massive tickling party on the offending party.
How do you handle statics? Theres never a reason to have a static local to a function so theres no reason to invent a syntax for it. But like for most absolute rules, there is an exception, that is when making singletons. Use a s_ prefix in this case. Take a look atSingleton Patternfor more details.
Static VariablesStatic variables may be prepended with s.JustificationIts important to know the scope of a variable.Exampleclass Test public: private: static StatusInfo msStatus;
These headers are structured in such a way as they can be parsed and extracted. They are not useless like normal headers. So take time to fill them out. If you do it right once no more documentation may be necessary.
I advocate simultaneously writing code, writing tests, and writing documentaiton. Which comes first depends on you and the problem. I dont think there is any rule that says which should come first. On the path to getting stuff done Ill take the entrance that seems easiest to me at the time. Once on the path its easy to follow the entire trail.
I dont really consider unit tests a question answering device because if you cant understand the code by reading it, reading something else about the code you dont understand wont help you understand it better.
Document DecisionsComments should document decisions. At every point where you had a choice of what to do place a comment describing which choice you made and why. Archeologists will find this the most useful information.
Means theres more to do here, dont forget.
Wont this break the flow? No, I think it improves flow because it keeps youmindfulof what you are doing, why you are doing, and how it fits in the big picture. My take on TDD (test driven development) is that its not the tests that are really important, its that the tests keep youmindfulwhile programming. A test means you are keeping everything in you mind at once you need to remember to successfully code something up. As you cant keep large chunks in your mind then smaller chunks are better. Writing a test forces you to remember what your code is supposed to accomplish. Its forcing you to also think about the use case/story/intent behind why you are writing the code.
Some subtle errors can occur when macro names and enum labels use the same name.Exampledefine MAX(a,b) blah define IS_ERR(err) blah
Take for exampleNetworkABCKey. Notice how the C from ABC and K from key are confused. Some people dont mind this and others just hate it so youll find different policies in different code so you never know what to call something.Exampleclass FluidOz // NOT FluidOZ class NetworkAbcKey // NOT NetworkABCKey
Source File Extension DiscussionThe problem with the.Cextension is that it is indistinguishable from the.cextensions in operating systems that arent case sensitive. Yes, this is a UNIX vs. windows issue. Since it is a simple step aiding portability we wont use the.Cextension. The.cppextension is a little wordy. So the.ccextension wins by default.
ContentsTo make comments on this page please see the newDisqus comment section. Pferor was also nice enough to make a copy of this document available inpdf format.IntroductionStandardization is ImportantStandards EnforcementAccepting an Idea6 Phases of a Project(joke)Flow Chart of Project Decision Making(joke)On LeadershipResources- Take a Look!GeneralBook RecommendationsNamesMake Names FitInclude Units in NamesNo All Upper Case AbbreviationsClass NamesClass Library NamesMethod NamesClass Attribute NamesMethod Argument NamesVariable Names on the StackPointer VariablesReference Variables and Functions Returning ReferencesGlobal VariablesGlobal ConstantsStatic VariablesType NamesEnum Namesdefine and Macro NamesC Function NamesC++ File ExtensionsDocumentationComments Should Tell a StoryDocument DecisionsUse Extractable HeadersComment All Questions a Programmer May Have When Looking at Your CodeMake Your Code Discoverable by BrowsingWrite Comments as You CodeMake Gotchas ExplicitInterface and Implementation DocumentationDirectory DocumentationInclude Statement DocumentationBlock CommentsComplexity ManagementLayeringMinimize Dependencies with Abstract Base ClassesLiskovs Substitution PrinicpleOpen/Closed PrincipleRegister/Dispatch IdiomDelegationFollow the Law of DemeterDesign by ContractClassesNaming Class FilesClass LayoutWhat should go in public/protected/private?Prototype Source FileUse Header File GuardsRequired Methods for a ClassMethod LayoutFormating Methods with Multiple ArgumentsDifferent Accessor StylesInit Idiom for Initializing ObjectsInitialize all VariablesMinimize InlinesThink About What Work to do in ConstructorsDont Over Use OperatorsThin vs. Thick Class InterfacesShort MethodsIn a Source file Indicate if a Method is Static or VirtualProcessUse a Design Notation and ProcessUsing Use CasesUsing StoriesUnified Modeling LanguageCode ReviewsCreate a Source Code Control System Early and Not OftenCreate a Bug Tracking System Early and Not OftenCreate a Wiki System Early and Not OftenRCS Keyword, Change Log, and History PolicyHonor ResponsibilitiesProcess AutomationTools AgreementNon-Blocking SchedulingUsing PersonasUse a Continuous Build SystemCode in the Dominant StyleRun Unit Tests Before Every Check-inFormattingBracePolicyIndentation/Tabs/Space PolicyParens()with Key Words and Functions PolicyA Line Should Not Exceed 78 CharactersIf Then ElseFormattingswitchFormattingUse ofgoto,continue,breakand?:One Statement Per LineAlignment of Declaration BlocksDocument Null StatementsIncludestaticandvirtualKey Words in Source FileExceptionsCreate One Exception for Each LibrarySelecting Between Exceptions And AssertsBe Careful Throwing Exceptions in DestructorsWorking With Libaries Using All Sorts of Different PoliciesTemplatesNamespacesCreate Unique Name Space NamesDont Globally DefineusingCreate Shortcut NamesMiscellaneousBe Const CorrectPlacement of the Const QualifierUse StreamsNo Magic NumbersError Return Check PolicyTo Use Enums or Not to Use EnumsMacrosDo Not Default If Test to Non-ZeroThe Bull of Boolean TypesUsually Avoid Embedded AssignmentsReusing Your Hard Work and the Hard Work of OthersCommenting Out Large Code BlocksUse if Not ifdefCreating a C Function in C++Mixing C and C++No Data Definitions in Header FilesMake Functions ReentrantUse the Resource Acquisition is Initialization (RAII) IdiomRemove Trailing WhitespacePortabilityUse Typedefs for TypesAlignment of Class MembersCompiler Dependent ExceptionsCompiler Dependent RTTIPopular MythsPromise of OOYou cant use OO and C++ on Embedded Systems
Reference Variables and Functions Returning ReferencesReferences should be prepended with r.JustificationThe difference between variable types is clarified.It establishes the difference between a method returning a modifiable object and the same method name returning a non-modifiable object.Exampleclass Test public: void DoSomething(StatusInfo StatusInfo& rStatus(); const StatusInfo& Status() const; private: StatusInfo
Oh yah – one more thing. Project leaders: TAKE the blame when things go wrong and SHARE the credit when things go right.
Tells somebody that the following code is very tricky so dont go changing it without thinking.
For example: RetryMax to mean the maximum number of retries, RetryCnt to mean the current retry count.
Class Library NamesNow that name spaces are becoming more widely implemented, name spaces should be used to prevent class name conflicts among libraries from different vendors and groups.When not using name spaces, its common to prevent class name clashes by prefixing class names with a unique string. Two characters is sufficient, but a longer length is fine.ExampleJohn Johnsons complete data structure library could useJJas a prefix, so classes would be:class JjLinkList
Include Units in NamesIf a variable represents time, weight, or some other unit then include the unit in the name so developers can more easily spot problems. For example:uint32 mTimeoutMsecs; uint32 mMyWeightLbs;Better yet is to make a variable into a class so bad conversions can be caught.
Thats when a Project Leader is required. Unless you want to flip a coin.
Classes are often nouns. By making function names verbs and following other naming conventions programs can be read more naturally.
So when you do something document it right then and there. When you create a class- document it. When you create a method- document it. And so on. That way when you finish coding you will also be finished documenting.
If you find all your names could be Thing and DoIt then you should probably revisit your design.Class NamesName the class after what it is. If you cant think of what it is that is a clue you have not thought through the design well enough.Compound names of over three words are a clue your design may be confusing various entities in your system. Revisit your design. Try a CRC card session to see if your objects have more responsibilities than they should.Avoid the temptation of bringing the name of the class a class derives from into the derived classs name. A class should stand on its own. It doesnt matter what it derives from.Suffixes are sometimes helpful. For example, if your system uses agents then naming something DownloadAgent conveys real information.Method and Function NamesUsually every method and function performs an action, so the name should make clear what it does: CheckForErrors() instead of ErrorCheck(), DumpDataToFile() instead of DataFile(). This will also make functions and data objects more distinguishable.
For some reason an odd split occurred in early C++ compilers around what C++ source files should be called. C header files always use the.hand C source files always use the.cextension. What should we use for C++?
You have a lot of tools at your disposal to answer questions:A brain to think up the questions you should be answering. Why? Who? When? How? What?Variable names.Class names.Class decomposition.Method decomposition.File names.Documentation at all levels: package, class, method, attribute, inline.The better you are at orchestrating all these elements together the clearer your code will be to everyone else.
Write Comments as You CodeYou wont every go back later and document your code. You just wont. Dont lie to yourself, the world, and your mother by saying that you will.
The result is a pointed mind that has focussed all its powers on doing one thing. When you can bring that focus to you programming you can be successful. The tests are really secondary. If your system/acceptance tests cant find bugs you are screwed anyway. And I find code written mindfully, one step at a time, has very few bugs. Unit tests are just one definition of a step. You can use the orignial story you are implementing as a step as well. I use unit tests more as a mental focussing device while developing, like Zen Archery, than for the actual tests. After development unit tests are very useful in making sure code doesnt break. So I am not saying unit tests arent useful. I just dont think they are the real reason behind why TDD generates working code. With a clear well functioning focussed mind we generate working code. But getting into that state is hard.
Software is ultimately mind stuff. Using our minds better is the real methodology.
Type NamesWhen possible for types based on native types make a typedef.Typedef names should use the same naming policy as for a class with the wordTypeappended.JustificationOf all the different naming strategies many people found this one the best compromise.Types are things so should use upper case letters.Typeis appended to make it clear this is not a class.Exampletypedef uint16 ModuleType; typedef uint32 SystemType;
Comments Should Tell a StoryConsider your comments a story describing the system. Expect your comments to be extracted by a robot and formed into a man page. Class comments are one part of the story, method signature comments are another part of the story, method arguments another part, and method implementation yet another part. All these parts should weave together and inform someone else at another point of time just exactly what you did and why.
Writing comments simultaneously with all other aspects of development deepens your mindfulness because you are thinking about everything at once. All the interconnections are present in your brain because you are explaining the intent behind what you are doing.
Gotcha FormattingMake the gotcha keyword the first symbol in the comment.Comments may consist of multiple lines, but the first line should be a self-containing, meaningful summary.The writers name and the date of the remark should be part of the comment. This information is in the source repository, but it can take a quite a while to find out when and by whom it was added. Often gotchas stick around longer than they should. Embedding date information allows other programmer to make this decision. Embedding who information lets us know who to ask.Example// :TODO: tmh 960810: possible performance problem // We should really use a hash table here but for now well // use a linear search. // :KLUDGE: tmh 960810: possible unsafe type cast // We need a cast here to recover the derived type. It should // probably use a virtual method or template.See AlsoSeeInterface and Implementation Documentationfor more details on how documentation should be laid out.