What does Larry's style look like?

Sorry this took so long - work's been really busy lately.

Clearly I'm not enough of an egotist[1]  to believe that my style is in any way the "one true style", but over the course of writing the series on style, I realized that I've never written down my current coding style, and I think it would be vaguely humorous to write down "Larry's Coding Conventions".

So here goes.  I'm using the keywords defined in RFC2119 within.

Larry's Coding Conventions

1. Files - Global file information.

All source files (.C, .CXX, .CPP, etc) MUST be plain text files, with CR/LF (0x0D0x0A) at the end of each line.  Each file MUST end with a CRLF.  C++ code SHOULD be in files with an extension of .CPP, C code SHOULD be in files with an extension of .C.  Header files SHOULD have an extension of .H.

Tab size MUST be set to 4, and tab characters MUST NOT appear in source files, this allows for a user to use any editor and still have the same experience while viewing the code.

Every source file MUST start with the following header:

/*++ * <Copyright Notice (talk to your legal department for the format of the copyright notice)> * * Module-Name: *     <file name> * * Author: *     <author full name> (<author email address>) <date of creation> * * Abstract: *     <Brief abstract of the source file> * * Revision History: * *--*/ Filenames SHOULD be representative of the contents of the files.  There SHOULD be one class (or set of functionality) per file.  So the CFoo class should be located in a source file named "Foo.cpp".

Global variables SHOULD begin with a prefix of g_.  Care MUST be taken when declaring global variables, since they are likely sources of synchronization issues.

Source code lines SHOULD be no longer than 100 characters long.

2. Class definitions

All classes SHOULD start with C in the class name.  Member variables of classes MUST start with an _ character.   Member variables are PascalCased (so a member variable could be _MyMemberVariable).

Classes that are reference counted SHOULD follow the OLE conventions - an AddRef() and a Release() method should be used for reference counting.  If a class is reference counted, then the destructor for that class SHOULD be private.

3. Functions and Methods - Info pertaining to various functions.

Each routine MUST have a function header, with the following format:

/*++ * Function Name * *     <Description of the function> * * Inputs: *     <Description of the parameters to the function, or "None."> * * Returns: *     <Description of the return value, or "None."> * * Remarks: *     <Relevant information about the function, may be empty> *  *--*/ 

Function names SHOULD be representative of their function.  All function names MUST be in PascalCase as per the CLR coding standards.  If the project is using an auto-doc tool, it's acceptable to tag the inputs closer to their definition.

Parameters to functions are also in PascalCase (note that this is a difference from the CLR coding standard).

Local variables in functions should be camelCased.  This allows for the reader to determine the difference between local variables, parameters and class members easily.

Parameter names SHOULD NOT match the names of methods in the class.

Code SHOULD have liberal use of vertical whitespace, with descriptive block comments every five or so lines of source code.

Descriptive comments SHOULD have the format:

    :    :    //    //<space><space>Descriptive Comment Line 1    //<space><space>Descriptive Comment Line 2    //    :    :

Each descriptive comment starts 4 spaces from the left margin, there is a single empty comment line before and after the descriptive comment, and two spaces between the // and the start of the comment text.

Functions SHOULD occupy no more than one screen, or about 70 lines, including comments (not including headers).  This means that each function SHOULD be at most about 40 lines of code.

4. Predefined Identifiers (Manifest Constants)

Manifest constants SHOULD be in all upper-case.  Instead of using #define, enum's or const's SHOULD be used when possible, especially if the value being defined is unique, since it allows for better representation in the debugger (yeah, I know I've said that source level debuggers are a crutch, but...).

5. Code layout

Code is laid out using BSD-style - braces appear on their own line at the same indentation level as the conditional, code is indented 4 spaces on the line after the brace.

So an if/else statement is formatted as:

    if (i < 0)    {        i += 1;    }    else    {        i += 1;    }

In general, unless semantically necessary, I use <variable> += 1 instead of <variable>++ or ++<variable>.

Variable declarations SHOULD appear each on their own line.

6. Code Example

The following is an example of code in "Larry's Style".

/*++ * ErrorPrint * *     Print a formatted error string on the debug console. * * Inputs: *     Format - printf style format specifier * * Returns: *     None. * * Remarks: *     The total printf string should be less than DEBUG_STRING_BUFFER_SIZE bytes. *  *--*/static void ErrorPrint(LPCSTR Format, ...){    int result = 0;    static char outputBuffer[DEBUG_STRING_BUFFER_SIZE];    va_list marker;    va_start(marker, Format);    result = StringCchVPrintfA(outputBuffer, DEBUG_STRING_BUFFER_SIZE, Format, marker);    if (result == S_OK)    {        OutputDebugStringA(buffer);    }    va_end(marker);}

 

[1] Ok, I've got a blog, that makes me an egotist, but not enough of an egotist[2]
[2] Apologies to KC for stealing her footnoting style :)

Edit: pszFormat->Format.