Coding Conventions for AppleWin =============================== History: 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. For variables use lower camel case. 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; }; Simple loop counters (i,j,k) don't need to adhere to this style. 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. 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 e : enum variable h : handle i : iterator (eg. UINT, STL-iterator) m : STL map n : int r : reference s : string sg_p : singleton u : unsigned int v : STL vector