Before You Commit:  

Assume that all code will be reviewed.

(Sooner or later it all will. It all needs maintenance, so someone eventually re-reads all of it.) 

Treating all code as though someone will immediately read it and try to follow it leads to better code.

 

Write a commit message that makes sense.

Think of what the code review assignment email looks like!  Your note is shown in isolation.  Make it clear.  

(In other words, not just "continuation of yesterday's work" -- because "yesterday's work" will likely not be shown adjacent to this comment in the assignment email!)

 

Commit often!  If some functionality is not yet complete, just place a 'wxFAIL' or a 'wxFAIL_MSG' to warn anyone who hits that code.

Committing often is important because it makes it easier for all of us to merge each other's changes before anyone diverges enough to make merging a significant hassle.

 

The commit message should be tagged with a BugzID number.

If there is no relevant BugzID that you can use, then consider opening a new bugtracker case.  (Obvious exceptions would be small commits where a function was renamed for clarity or something like that.  No sense opening a case for that.)

 

Only one bug/feature per commit. No mixing unrelated work into one commit!

If you are struggling with how to do this, then you probably need to study more git manuals and git tutorials.  Git provides an enormous amount of flexibility in selecting what to commit.

 
If your changes affect submodules (sub-repos), then commit them and synchronize everything correctly (e.g. Licensing-Repo and Common-Util-Repo)  
If you are adding a significant new feature, then *please* add new files!  It is a good thing when we can extend the program by adding new classes instead of tinkering (and possibly breaking) existing ones.  
If the code is based on an internet or book resource, please note this in comments.  
In new files, add the proper comment-block at top. (If the file is generated by DialogBlocks, then nevermind. Leave it as is.)  
If a new function is reusable, write it accordingly and put it in Common-Util-Repo.  

Source files in 'Common-Util-Repo' and 'Licensing-Repo' should not pound-include Main-Application files. General rule: library code cannot pound-include headers that are application headers from the EXE that links to the library.

 
If you use a wxWidgets or Qt class or function that is new to you, read the WHOLE documentation page for it. Playing with the wx or Qt sample is recommended, too.  
When editing a class or function, read all comments for the class and function, and be sure to update or remove any comments rendered inaccurate by your changes.  Be sure to check header and cpp file for comments. (It's good to read all commentary anyway -- sometimes it leads you to better and/or fewer changes by calling your attention to something you missed in pure code-reading.)  

 

 

Style Guidelines - Strive to Make All Code Follow These:  
With any if/else blocks, try to put the SHORTEST logic *first* (in the 'if' portion) and the longer logic in the 'else'. (Otherwise, when you read down through a looooong if-block and then notice "oh hey there is an else here" then you sometimes forget else what!!)  
When using '#ifdef' or '#ifndef', always put a comment on the '#endif' (in other words: on the closing end) that shows which '#if' is being closed/terminated !!  
Never put "using namespace" in a header. Also: when putting this in a cpp file, put it after all pound-includes.  
Never store full-blown objects in STL containers.  Instead, store shared_ptr(s) to the objects.  
Do your best to avoid creating any new "Data Class". A Data Class is *not* object-oriented and does not perform proper encapsulation/data-hiding.  We have some already, but avoid them in new code.  
Do not indulge in "Speculative Generality"  
Any time you encounter "Message Chains", try to see if the chain can be shortened!  
Never put a 'return' in the middle of a function! Strive for only a single 'return' per function.  One small exception is an "early return" near the very top, simply to avoid the nesting of an extra "if ( some_fatal_condition )" pushing nesting into the whole function body.  
Remember that the string "Trim" function in wxWidgets is silly. We usually want to call all this:  some_var.Trim(false).Trim(true)  
Instead of adding a bunch of wxLogDebug calls that are all related, *please* create a new trace mask instead.  
Do not commit commented-out code.  If the code is no longer needed, remove it.  It is safely stored in git, anyway.  If you are strongly tempted to leave it in, then consider replacing it with a comment such as: "some apparently obsolete code used to be here. please refer to a version of this file as of 15-March-2010 or earlier to retrieve the old code from version control."  
No function body should be all-on-one-line, like '{ return true; }' -- this sometimes makes it impossible to set a breakpoint in there.  
For comments about how to *use* your function or class, please use doxygen-style comments.  
Avoid deep (tall) inheritance hierarchies.   
Do not fear "wide" inheritance. A wide inheritance hierarchy, especially a single depth of many sibling children, is acceptable and many times is a sign of good polymorphism.  
Is "virtual" tacked onto a function for a reason?  We don't need to blindly add virtual everywhere. (Dtors are the exception to the rule. It's ok to religiously put 'virtual' on all dtors. It would be dangerous if we later subclassed and forgot to add it then.)  
Avoid usage of "friend class" in new code. In extreme cases you may friend a single function.  (But passing an anonymous 'wrapped' functor using boost::function is perhaps a better way to allow other code to 'call' your private function.)  
Do not use multiple inheritance EXCEPT when using pure virtual pure abstract "interfaces." If we are only dealing with pure abstract interfaces, we can be a bit bolder.  

 

 
Checklist. Answer These For Each Code Review:  
Is there sanity-checking on return values? If something even *potentially* returns an error value, *always* do sanity checking on it.  
Are all new data-members private?  
Even new data-members made by DialogBlocks should usually be private.  DialogBlocks does not insert the 'private:' line, so you must do it yourself.  
Do all the new pound-include directives appear in CPP files only? Use forward declarations and shared_ptr in headers to help with this.  
Are headers for new classes "self-sufficient"?  What this means in practice is that in any newly-added CPP file, the very topmost pound-include *must* be the #include for the header that goes with that cpp.  This compiler will then scan that header first, before having pulled in any other 'wx' or 'boost' things, which then proves that your new header is "self-sufficient" (i.e. not secretly depending on some other item just 'coincidentally' getting pound-included beforehand). [See "Coding Standards" book, item 23.]  
There is no duplicate code? Even four lines of code are enough to make a helper function.  
Any new compiler warnings? Code must not introduce any new compiler warnings  
Code must not cause tests to fail. Either fix the code or update the test. Otherwise, inform everyone why a test must temporarily fail.  
If a copy ctor changed, then did the operator= function change accordingly?  
If the operator= changed, then did the copy ctor change accordingly?  
If a member variable is added or moved, then did the member initialization list in the ctor get updated?  
If the keyword 'new' is used anywhere other than in a shared_ptr, then are we certain no leaks got introduced?  
Was all usage of printf-style string formatters done correctly? All '%' placeholders must be correctly matched to the corresponding variable parameter. Achieving crashes and (worse!) corruption is all too easy with formatters.  
If the type of a variable was changed, then did printf(s) change accordingly? If a variable changed (from int to bool, or from int to float, for example), then watch out to see if this variable is passed to any printf-style function that relied on the prior type!  
Are sufficient assertions utilized to flag assumptions and potential misuse/misbehavior of code?   (but also see next item)  
Do we need to choose a RELEASE-MODE error instead of an assertion anywhere? (assertions disappear in release build)  
If a ctor takes exactly one parameter, then did we add 'explicit'?  
Did we explicitly disallow copying (unless there is an exceptional need)? (this is to be done using DECLARE_NO_COPY_CLASS or boost::noncopyable)  
Did we use const wherever possible? (member functions, parameters, some local variables, etc)  
Did we avoid preprocessor usage? (aka avoid "macros")  
Did we avoid default values in member function parameter declarations? (especially in virtual inherited functions)  
Is casting used correctly?  (even better if we can code without any need for casting...) Be very wary of casting!  Refer to Effective c++ third edition, Item 27  
Did we avoid the 'inline' keyword?  It is only a compiler hint and is rarely needed or effective. Refer to Effective c++ third edition, Item 30  
Are (non-template) function bodies kept strictly to the cpp file? (since we just said the 'inline' is not to be used), there is no reason to put function bodies in the header. Please keep them in the cpp. However, see next item for the template case.  
Are template definitions (bodies) kept *in* the header, together with declarations? All new template classes should have a single header file per class and no cpp file. This follows the "inclusion model" in 6.1.2 of this book (C++ Templates).  
Have we verified there are no bare literal magic numbers??!!  If some interesting number is required, then at least make some const value with an explanatory name, and probably a comment, too.  
Are we using "Introduce Explaining Variable" whenever possible?  
Are all variables always initialized?  Do not ever leave something like:  "int factor;"  (instead, type an "=" after the var name and initialize!)  
Have we only returned 'safe' objects and data from any new functions?  Do not return pointers to private member variables!  (some existing code does this. avoid it in new code.)  
Did we do boundary checking before any and all '[i]' access? (arrays/vectors/deques/etc)? Good loop conditions can qualify as sufficient checking.  
Are variable names clear?  (Don't be afraid to suggest a rename to the original coder.)  
Are function names clear?  (Don't be afraid to suggest a rename to the original coder.)  
Are comments clear?  (Don't be afraid to suggest a rewording to the original coder.)  
Are error messages and assertion-failure messages clear?  (Don't be afraid to suggest a rewording to the original coder.)