AppleWin/docs/CodingConventions.txt
2023-03-23 08:47:38 -07:00

231 lines
6.2 KiB
Plaintext

Coding Conventions for AppleWin
===============================
History:
v7 - 23-Mar-2023 (MP)
. Clarify 2.1 Naming
. Split into sub-section 2.1.1: Simplified prefix names
. Split into sub-section 2.1.2: Loop conters
. Split into sub-section 2.1.3: Out parameters
. Clarify 2.6 Indentation
. Add 2.6.1: Brace placement
. Add 2.6.1.1: Debugger function style
. Clarify b, and n prefix
v6 - 12-Jan-2023 (TC)
. Avoid global vars & provide getter/setter accessor functions.
. Avoid C++11 empty initializer lists. (PR#634)
v5 - 03-Apr-2022 (TC)
. #1072: Add a space after keywords.
v4 - 05-Mar-2022 (TC)
. #1050: Added info about Platform Toolset v141_xp
. Use of C++11/14/17
. Use StrFormat() instead of sprintf() etc.
v3 - 14-Nov-2020 (TC)
. #868: Reduced Hungarian notation
v2 - 16-Feb-2006 (TC)
. Updated after discussion with M.Pohoreski
v1 - 04-Feb-2006 (TC)
. First draft
-------------------------------------------------------------------------------
Introduction:
-------------
This doc defines a very simple set of coding guidelines to be used for AppleWin.
This ensures consistency & readability throughout the project, when worked on
by multiple developers.
-------------------------------------------------------------------------------
1) Project files:
1.1: Each module to have corresponding header
EG. Debug.cpp has a corresponding Debug.h
This is for shared vars, enums, structs, classes, etc.
1.2: AppleWin.h to only be used as per 1.1
1.3: Common.h to be used for any common definitions
EG. const/enum/struct
Obviously not for global funcs or vars.
1.4: At the start of each header file it must contain: #pragma once
1.5: Each module (.cpp) to include stdafx.h, and then immediately after include
the header file for that module.
EG. For Debug.cpp:
#include "stdafx.h"
#include "Debug.h"
This ensures that this header file can be included in any order in another module,
and therefore by extension all header files can be included in any order.
-------------------------------------------------------------------------------
2) Coding Style:
As a general rule and for consistency, adopt the coding convention/style of any module (or function) you are modifying.
2.1: Naming
For functions use upper camel case (PascalCase).
For variables use lower camel case (camelCase).
2.1.1: Simplified prefix names
And only if applicable, the following simplified prefix (Hungarian) style can be used:
Prefixes:
g_ : global
m_ : member
p : pointer
Tags:
_e : named enum definitions
_t : struct/typedef
Also see: "Appendix: Legacy Hungarian notation"
EG:
enum MODE_e {MODE1, MODE2, MODE2};
MODE_e mode;
struct PAIR_t
{
UINT a;
UINT b;
};
2.1.2: Loop conters
Simple loop counters (i,j,k) don't need to adhere to this style.
NOTE: It would be better to use a better descriptive loop name then a non-descript single character variable name.
2.1.3: Out parameters
Naming for parameters that are being modified (eg. OUT):
It is recommended (but not mandatory) to use a suffix of OUT or '_', eg:
bool Find(int* pFoundOUT);
bool Find(int* pFound_);
2.2: Matching braces
These should be have same indentation, unless the braces fit neatly on one line.
EG:
for (int i=0; i<10; i++)
{
// Some code
}
2.3: Scope of module vars/funcs
If module vars/funcs aren't wrapped in a class, then declare as static if not global.
2.4: const/enum favoured over #define
Try to use const/enum instead of #define
2.4: Use of bool over BOOL
Always use bool instead of BOOL
2.5: File header
GPL header, followed by description of module & author.
2.6: Indentation
Tabs favoured over spaces. (Tabs for indent, spaces for alignment.)
2.6.1: Brace placement
Braces should be formated with Allman Style (opening brace on separate line) and NOT K&R style (opening brace on same indentation level as its header).
EG:
void FindFoo() // GOOD
{
}
void FindFoo() { // BAD
}
See: https://en.wikipedia.org/wiki/Indentation_style
2.6.1.1: Debugger function style
For functions in the debugger, both the
* function declaration,and
* function definition
MUST have a space between the end of the function name and the opening parenthesis.
This makes it trivial to search and jump to the function implementation since every function call _won't_ have that extra space.
EG:
void FindFoo (); // .h
void FindFoo () // .cpp
{
}
void Bar()
{
if (FindFoo() // usage
}
2.7: Expression to be well spaced and parenthesised
It is recommended (but not mandatory):
. to have/use explicit parenthesis
. to have spaces between operators
EG:
. Prefer: z = ((a + b) + 1) instead of: z=((a+b)+1)
2.8: Add a space after keywords (if, for, switch, while, etc).
EG:
for (int i=0; i<10; i++)
Not:
for(int i=0; i<10; i++)
2.9: Avoid global variables.
If a free variable exists within a C++ file, then declare it static and provide getter & setter accessor functions.
-------------------------------------------------------------------------------
3) Use of sprintf() etc.
Do not use sprintf(), StringCbPrintf(), wsprintf(), etc. - instead use StrFormat().
-------------------------------------------------------------------------------
4) Use of C++
VS2019's Platform Toolset "Visual Studio 2017 - Windows XP(v141_xp)" is used for building releases.
This is VS2017 v15.0, which includes support for C++11, C++14 and some C++17 core language support[1].
[1] https://docs.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance?view=msvc-170
4.1: Type deduction (including auto)
Use type deduction only if it makes the code clearer to readers who aren't familiar with the project,
or if it makes the code safer. Do not use it merely to avoid the inconvenience of writing an explicit type.
(Ref: https://google.github.io/styleguide/cppguide.html#Type_deduction)
4.2: Avoid C++11 empty initializer lists
This notation can be too obscure, compared to using regular initialization (for POD) or ctors (for classes).
EG, avoid this:
int var {};
struct s {};
-------------------------------------------------------------------------------
Appendix: Legacy Hungarian notation
dw : DWORD
sz : string (null-terminated)
a : array
b : bool or bitmask
e : enum variable
h : handle
i : iterator (eg. UINT, STL-iterator)
m : STL map
n : int, total, or length
r : reference
s : string
sg_p : singleton
u : unsigned int
v : STL vector