Finally there are some links to other sites which contain coding standards and related information
Speed Now: | Optimisations are NOT deferred to late in
the project provided making them can
speed up testing / development. It's generally accepted wisdom that one should make it 'work right' before one makes it 'work fast'. This can mistakenly be taken to the length of postponing optimisation till the end of a project. I have found slow versions of my software slowing testing and development as badly as a very slow compiler would. |
Output Caches: | When designing an in-class cache to speed up
a function, it should be an OUTPUT cache. This is to ensure caching
strategies are compatible between classes (i.e classes can be strung
together). Prior to this rule, I'd written pairs of classes where one class had an output cache, and it fed in to an input cache of another - a wombat (trans. Waste Of Money Brains And Time). |
Think Extensions: | Code for 'squares' should be written with
extension to both cubes (and higher) and extension to triangles,
pentagons (and higher) in mind. This is best achieved by recognising that points, edges and faces have different types. For example corners of a polygon are fenceposts to the edges, and therefore an explicit function to move from edge to one or other corner is needed. By contrast, use of an edge index as if it were the same thing as a point index does not generalise to polyhedra. |
Think Tabular: | Look for ways to make the code more regular. Switch statements tend to accumulate clutter. Aim to make them regular in their structure with future migration to table driven code in mind |
Coordinate conversions and fencepost to
fence conversions should be designed items, not ad-hoc conversions
as and where needed. If efficiency is an issue here, use inline
functions, but make the conversion explicit. An example, a text 'cursor' is a fencepost object for it appears between characters. It's position therefore is of a different type to that of a character, and a function call to get the index of the character after it or of the charcter before it should be made. |
Disable Obsoletes: | When moving variables between classes or renaming, always delete or comment out the old variable declaration to ensure ALL cases of its use have been caught. |
Dead Code: | It is O.K. to leave dead code commented out in the source. Normal development will involve commenting out dead code. Such code may finally be removed much later, when it is clear it can no longer be useful. |
Duplicates: | It's O.K. to have two copies of similar algorithms, where a variant is being debugged. However, a long term goal should be to merge back these subroutines where the performance hit in 'worst case' is less than 10%. |
Outparams First: | In functions, arguments used to return
results should precede arguments which give data, e.g FuncCopy(
pDest, pSource); This is the same order as in memcpy and assignment. A refinement of this rule applies to classes. Function return values (where non void), count as the first argument. The implicit class variable (*this) counts as the next argument. A function which reads one class variable and writes another would be a member function of the class which it updates. The function would have the class it reads as an argument. This rule thus determines which of two classes a function of two class variables belongs in. |
While Iterators: | Iterators should be for use in 'while' loops
rather than in 'for' loops. Define a First() and a More() function -
no need for a Next() function. The function First() should take an argument specifying the kind of iteration as this reduces the number of different iterator classes one defines. |
Use Spaces: | The editor should be set to use spaces not
tabs for indenting. One indent is three spaces, except for code
auto-generated by MSVC wizards. I have been caught out by printers that define tab sizes differently. |
Constants should be given names where this improves clarity. This is particularly important for lengths, pixel positions and scale factors. | |
Avoid Bools: | For readability of calls to a function and to promote future upgrades, avoid BOOL arguments to functions. Use, for example, an option code. |
Undo Reverses: | Aim to 'undo' operations in the reverse order to which they were done, increment then store becomes retrieve then decrement. Constructor / Destructor pairs may be useful to achieve this. |
Don't use the facility which allows a
variable's declaration to be combined with a calculated assignment
to that variable. Because I use a variant of Hungarian notation (I use the p and sz prefixes), I find that I rarely need to look at declaration of variable types. I do need to look at assignments. Having declarations and assignments in separate chunks helps me to find what I need to faster. All the local variable type declarations are at the of a subroutine close to the subroutine's paramater variable type declarations. | |
Range [,) | In comments describing ranges use the [0,3.7) convention where '[' indicates inclusive, ')' indicates exclusive. |
Range Spec | Ranges should be represented as start and nItems rather than as start and end. |
Related Names: | Look to create groups of related names rather than once-offs, and prefer naming where the repeated part comes first (which is useful for tracking related quantities in alphabetic listings). Exception: When providing functions like system provided ones, use names following system conventions, e.g CircleBlt(), ShrinkBlt(). | |||||
American Spelling: | Colour is spelt with a 'u' Exception: system provided identifiers/macros such as COLORREF use the American spelling. Normalize with a 'z' not an 's'. | |||||
Capitalisation: | For purposes of capitalisation, these words
are treated:
| |||||
Avoid redundancy in names, e.g DibHandle, not MyDibHandle. | ||||||
Be Specific: | Be specific e.g. 'Points' or 'Positions' is preferred to more generic terms 'Values', 'Data'. | |||||
Positive Naming: | Use positive naming, e.g. IsVisible() or IsHidden(), not IsInvisible(). | |||||
Abbreviations: | Abbreviations should only be used where the
number of characters saved is significant taken over the whole
program, i.e. abbreviate long names used many times. Capitalise only the first letter of All-Caps abbreviations. This is a uniform way to distinguish lexical units in compound names (e.g. use Dib not DIB). Standard abbreviations should be added to this list here:
| |||||
Standard Pairs: | When naming 'inverses' use standard pairs.
Add to this list here:
| |||||
Conversion names: | Name conversion functions using
Type1OfType2() for functions which act as a prefix, Type1ToType2()
for class functions which act as a suffix. This is so that
conversions can be read as:
| |||||