Changes between Version 1 and Version 2 of Coding_Conventions


Ignore:
Timestamp:
Jun 24, 2009, 12:25:58 AM (15 years ago)
Author:
Philip Taylor
Comment:

import coding_convention.tex into wiki

Legend:

Unmodified
Added
Removed
Modified
  • Coding_Conventions

    v1 v2  
    1  * by Dave Loeser
    2  * Version 1. 12
    3  * 10 February 2004
    4 
    5 = Objective =
    6 
    7 The goal of this document is to provide a standardized coding methodology for the 0 A.D. programming team. With but a few guidelines such as Layout, Commenting and Naming conventions the team should feel as if they are reading their own code when reading someone else�s code.
    8 
    9 == Forewarning ==
    10 
    11 Since this document was created after the start of preliminary coding, there may be source code that does not follow the guidelines as dictated by this document.
    12 
    13 The team will, as time permits, make an effort to update those sources.
    14 
    15 = Layout =
    16 
    17 == Formatting ==
    18 
    19 Most editors allow for the conversion of tabs to spaces and most people prefer the use of tabs versus wearing the space-bar out.  The size of the tabs is up to each programmer � just ensure that you are using tabs.
    20 
    21 Limit the length of a line of code to not more than 80 characters; not everyone has a 1600x1200 resolution.  Functions that have many parameters and extend over 80 characters should be written:
    22 
    23 {{{
    24   SomeFunction(
    25       HWND hWnd_,
    26       BITMAP bmDeviceBitmap_,
    27       long lAnimationFrame_);
    28 }}}
    29 
    30 as opposed to
    31 
    32 {{{
    33   SomeFunction(HWND hWnd_,
    34                 BITMAP bmDeviceBitmap_,
    35                 long lAnimationFrame_);
    36 }}}
    37 
    38 Although the second method is commonly used, it is more difficult to maintain if the name of the function changed; you would need to re-align the parameters.
    39 
    40 == Brackets ==
    41 
    42 Brackets should be aligned, here�s an example of valid bracket alignment:
    43 
    44 === Good Bracketing ===
    45 
    46 {{{
    47   void CGameObject::CleanUp()
    48   {
    49       if(NULL != m_ThisObject)
    50       {
    51           delete m_ThisObject;
    52       }
    53   }
    54 }}}
    55 
    56 === Bad Bracketing ===
    57 
    58 {{{
    59   void CGameObject::CleanUp(){
    60       if(NULL != m_ThisObject){
    61           delete m_ThisObject;
    62       }
    63   }
    64 }}}
    65 
    66 We�re not out to save vertical lines on the screen; it�s about being able to read the code; reading code is a visual experience if not visceral.
    67 
    68 = Commenting and Documentation =
     1== Objective ==
     2
     3The goal of this document is to provide a standardized coding methodology for the 0 A.D. programming team. With but a few guidelines for layout, commenting and naming conventions, the team should feel as if they are reading their own code when reading someone else's code.
     4
     5== Layout ==
     6
     7=== Formatting ===
     8
     9Most editors allow for the conversion of tabs to spaces and most people prefer the use of tabs versus wearing out the spacebar. The size of the tabs is up to each programmer -- just ensure that you are using tabs.
     10
     11Limit the length of a line of code to not more than 80 characters; not everyone has a 1600x1200 display. Functions that have many parameters and extend over 80 characters should be written as:
     12{{{
     13   SomeFunction(
     14       HWND hWnd,
     15       BITMAP bmDeviceBitmap,
     16       long lAnimationFrame);
     17}}}
     18instead of:
     19{{{
     20   SomeFunction(HWND hWnd,
     21                BITMAP bmDeviceBitmap,
     22                long lAnimationFrame);
     23}}}
     24Although the second method is commonly used, it is more difficult to maintain (if the name of the function changed, you would need to re-align the parameters).
     25
     26=== Brackets ===
     27
     28Brackets should be aligned, here's an example of good bracket placement:
     29{{{
     30   void CGameObject::CleanUp()
     31   {
     32       if(NULL != m_ThisObject)
     33       {
     34           delete m_ThisObject;
     35       }
     36   }
     37}}}
     38Now we're not out to save vertical lines on the screen; it's about being able to read the code. Therefore, the following style should be avoided:
     39{{{
     40   void CGameObject::CleanUp() {
     41       if(NULL != m_ThisObject) {
     42           delete m_ThisObject;
     43       }
     44   }
     45}}}
    6946
    7047== Commenting ==
    7148
    72 Commenting is a subject that is sure to cause debate. I prefer minimum comments and maximum expressiveness in the code.  Examples of what is considered good and bad commenting style are shown below.
    73 
    74 === Bad Commenting Style ===
    75 
    76 {{{
    77   void CGameObject::SetModifiedFlag(bool flag)
    78   {
    79       // set the modified flag
    80      
    81       m_bModifiedFlag = flag;
    82   }
    83 }}}
    84 
    85 The above comments do not tell us anything that we don�t already know from reading the code, here�s a better approach.
    86 
    87 === Good Commenting Style ===
    88 
    89 {{{
    90   void CGameObject::SetModifiedFlag(bool flag)
    91   {
    92        // This sets the GameObjects modified
     49Commenting is a subject that is sure to cause debate, but minimal comments with maximum expressiveness are preferable. Bad commenting style is shown below:
     50{{{
     51   void CGameObject::SetModifiedFlag(bool flag)
     52   {
     53       m_ModifiedFlag = flag;    // set the modified flag
     54   }
     55}}}
     56The above comment does not tell us anything that we don't already know from reading the code; here's a better approach:
     57{{{
     58   void CGameObject::SetModifiedFlag(bool flag)
     59   {
     60       // This sets the CGameObject's modified
    9361       // flag, which is used to determine
    9462       // if this object needs to be serialized.
    95        
    96        m_bModifiedFlag = flag;
    97   }
    98 }}}
     63       m_ModifiedFlag = flag;
     64   }
     65}}}
     66
     67== Naming Conventions ==
     68
     69=== Filenames ===
     70
     71Filenames can be freely chosen, but to avoid problems on Unix systems, they should not contain spaces or non-ASCII characters. If the file serves to define one class, e.g. `CEntity`, the file would usually be called `Entity.h`.
     72
     73=== Namespaces ===
     74
     75Namespaces are used as a mechanism to express logical grouping.
     76
     77==== Global Scope ====
     78
     79Symbols belonging to the global namespace should be prefixed with `::`.
     80Example: The Win32 function `::OutputDebugString()` resides in the global namespace and is written with the scope operator preceding the function name.
     81
     82=== Classes ===
     83
     84Classes should use concise, descriptive names that easily convey their use.
     85
     86Classes are named using !PascalCase - capitalizing each word within the name visually differentiates them. Example: A class named `CGameObject` is preferred over `gameObject` or `cGameObject`.
     87
     88=== Functions ===
     89
     90Functions should use concise, descriptive names that provide innate clues as to the functionality they provide.
     91
     92Global and member functions should be named using !PascalCase. Example: A function named `SetModifiedFlag()` is preferred over `SetFlag()` or `setFlag`.
     93
     94=== Variables ===
     95
     96Variable should use concise, descriptive names that provide innate clues as to the data that the variable represents.
     97
     98Member variables should be prefixed with `m_`, but both `m_camelCase` and `m_PascalCase` may be used according to personal preference (either way, the prefix ensures clarity). Example: `m_GameObject` is more descriptive than `gobj`.
    9999
    100100== Documentation ==
    101101
    102 Each programmer is responsible for properly documenting their code.  During code review the code reviewer will ensure that interfaces or API�s are properly documented.
    103 
    104 The suggested method of documenting a Class is:
    105 
    106 {{{
    107   /*                                                                                                   
    108         CLASS           : CCivilian                                                             
    109         AUTHOR          : Dave Loeser - daklozar@insightbb.com                                 
    110         DESCRIPTION     : An object that represents a civilian entity.                         
    111                                                                                                        
    112         NOTES           : Notes regarding usage and possible problems etc...                           
    113   */                                                                                                     
    114 }}}
    115 
    116 Each method of a class should be documented as well and here is the suggested method of documenting a member function (continuing with CExample):
    117 
    118 {{{
    119   class CExample
    120   {
    121       public:
    122              CExample();
    123              ~CExample():
     102Each programmer is responsible for properly documenting their code. During code review the code reviewer will ensure that interfaces or APIs are properly documented.
     103
     104If the comments are formatted in a certain way, they will automatically be extracted and added to the relevant documentation file. It suffices to write them as follows (sample comment for a class):
     105{{{
     106   /**
     107    * An object that represents a civilian entity.
     108    *
     109    * (Notes regarding usage and possible problems etc...)
     110    **/
     111}}}
     112For single-line comments, `///` can be used as well. The comment text is inserted into the documentation, and can additionally be formatted by certain tags (e.g. `@param description` for function parameters). For more details, see the !CppDoc documentation.
     113
     114Each method of a class should be documented as well and here is the suggested method of documenting a member function (continuing with `CExample`):
     115{{{
     116   class CExample
     117   {
     118   public:
     119       CExample();
     120       ~CExample():
     121
     122       /**
     123        * This function does nothing, but is a good example of
     124        * documenting a member function.
     125        * @param dummy A dummy parameter.
     126        **/
     127       void ShowExample(int dummy);
     128   
     129   private:
     130       intptr_t m_ExampleData;          // Holds the value of this example.
     131       double m_FairlyLongVariableName; // Shows the lining up of comments
     132   };
     133   }}}
     134The ctor and dtor need not be commented --- everyone knows what they are and what they do. `ShowExample()`, on the other hand, provides a brief comment as to its purpose. You may also want to provide an example of a method's usage. Member data is commented on the right side and it is generally good (when possible) to line up comments for easier reading.
     135
     136=== Author and Modified By ===
     137
     138To promote collective code ownership and encourage making necessary fixes to modules that happen to be written by others, we will avoid explicitly mentioning the author at the top of the file. Such a tag could (subconsciously) be interpreted as "his code only", a condition we want to avoid because "he" might get run over by a bus (thus losing the only source of knowledge and expertise on that piece of code).
     139
     140On a similar note, we will also avoid modified-by tags. The reasoning is as above, with the additional wrinkle of having to figure out when exactly to consider oneself to have modified the code. Is it after a quick typo fix, adding 2 lines, a function, ...?
     141
     142Note that the authors of course retain copyright; we can also reconstruct the file history and find out all contributors via SVN revision information. The purpose of this measure is simplicity and improved cooperation and does not deprive anyone of credit.
     143
     144
     145=== Example ===
     146
     147Here is a sample header file layout, `Example.h`:
     148{{{
     149   /**
     150    * =========================================================================
     151    * File        : Example.h
     152    * Project     : 0 A.D.
     153    * Description : CExample interface file.
     154    * =========================================================================
     155    **/
     156   
     157   /*
     158   This interface is difficult to write as it really
     159   pertains to nothing and serves no purpose other than to
     160   suggest a documentation scheme.
     161   */
     162
     163   #ifndef INCLUDED_EXAMPLE
     164   #define INCLUDED_EXAMPLE
     165   
     166   #include "utils.h"
     167   
     168   /**
     169    * CExample
     170    * This serves no purpose other than to
     171    * provide an example of documenting a class.
     172    * Notes regarding usage and possible problems etc...
     173    **/
     174   class CExample
     175   {
     176   public:
     177       CExample();
     178       ~CExample():
     179   
     180       /**
     181        * This function does nothing, but is a good example of
     182        * documenting a member function.
     183        * @param dummy A dummy parameter.
     184        **/
     185       void ShowExample(int dummy);
     186   
     187   protected:
     188       int m_UsefulForDerivedClasses;
     189   
     190   private:
     191       uint8_t m_ExampleData;        // Holds the value of this example.
     192       int m_RatherLongVariableName; // Shows the lining up of comments
     193   };
     194   
     195   #endif    // #ifndef INCLUDED_EXAMPLE
     196}}}
     197From the above we can see that header guards are utilized. Header file comment blocks show filename, project and author; a short overview follows.
     198
     199The order of declarations ought to be: public followed by protected and finally by private.
    124200 
    125              // ShowExample()
    126              // This function does nothing, but is a good example of documenting
    127              // a member function.
    128              void ShowExample();
    129  
    130       private:
    131              U8     m_ExampleData;       // Holds the value of this example.
    132              U8     m_LongVariableName;  // Shows the lining up of comments
    133   };
    134 }}}
    135 
    136 Essentially, the CTOR and DTOR need not be commented � everyone knows what they are and what they do.  !ShowExample(), on the other hand, provides a brief comment as to its purpose. You may also want to provide an example of a methods usage.  Member data is commented on the right side and it is generally a good ideal (when possible) to line up comments for easier reading.
    137 
    138 = Naming and Coding Conventions =
    139 
    140 Naming and coding conventions cover two main areas:
    141 
    142  * Files and directory structures
    143  * Variables, functions and classes
    144 
    145 == Namespaces ==
    146 
    147 Namespaces are used as a mechanism to express logical grouping.
    148 
    149 == Global Scope Functions ==
    150 
    151 A function that is belongs to the global namespace should be prefixed with ::.
    152 
    153 ''Example:'' The Win32 function '''::!OutputDebugString()''' belongs to the global namespace and is written with the scope operator preceding the function name.
    154 
    155 == Variable Naming ==
    156 
    157 Variables should use concise, descriptive names that provide innate clues as to the data that the variable represents.
    158 
    159 == Function Naming ==
    160 
    161 Functions should use concise, descriptive names that provide innate clues as to the functionality they provide.
    162 
    163 ''Example:'' A function named '''!SetModifiedFlag()''' is preferred over '''!SetFlag()'''.
    164 
    165 Global and member functions should be named using ''Inclusive capitalisation.'' Inclusive capitalisation is a method that visually differentiates the words within a function name.
    166 
    167 ''Example:'' A function named '''!SetModifiedFlag()''' is preferred over '''setModifiedFlag()''' or '''setmodifiedflag()'''.
    168 
    169 == Class Naming ==
    170 
    171 Classes should use concise, descriptive names that easily covey their use. Classes should be named using ''Inclusive capitalisation''. Inclusive capitalisation is a method that visually differentiates the words within a class name.
    172 
    173 ''Example:'' Every game has objects and '''CGameObject''' is more descriptive than '''cGObj''' or '''CGobj'''.
    174  
    175 == Header Files ==
    176 
    177 Here is a sample header file layout.
    178 
    179 {{{
    180   /*
    181  
    182          CExample interface file.
    183  
    184          AUTHOR        : Joe Coder � joecoder@email.com
    185          MODIFIED BY   : Coder Johnson - coder@email.com
    186  
    187          OVERVIEW      : This interface is difficult to write as it really
    188                          pertains to nothing and serves no purpose other than to
    189                          suggest a documentation scheme.
    190   */
    191  
    192   #ifndef __CEXAMPLE_H__
    193   #define __CEXAMPLE_H__
    194  
    195   //
    196   // INCLUDES and COMPILER DIRECTIVES
    197   //
    198   #include �utils.h�
    199  
    200   //
    201   // DECLARATIONS
    202  
    203   /*
    204          CLASS         : CExample
    205          AUTHOR        : Coder Johnson - coder@email.com
    206          DESCRIPTION   : The CExample class serves no purpose other than to
    207                          provide an example of documenting a class.
    208          NOTES         : Notes regarding usage and possible problems etc...
    209   */
    210  
    211   class CExample
    212   {
    213        public:
    214  
    215             CExample();
    216             ~CExample():
    217  
    218             // ShowExample()
    219             // This function does nothing, but is a good example of documenting
    220             // a member function.
    221             void ShowExample();
    222  
    223        protected:
    224        
    225        private:
    226  
    227             U8     m_ExampleData;       // Holds the value of this example.
    228             U8     m_LongVariableName;  // Shows the lining up of comments
    229   };
    230  
    231   #endif // __CEXAMPLE_H__
    232 }}}
    233 
    234 From the above we can see that header guards are utilized. Header file comment blocks have been shortened to show the name of the module this file belongs to, the authors name and email address and a short overview.
    235 
    236 The order of declarations is public followed by protected and finally by private. See [http://code.wildfiregames.com/resources/development/CCivilian.h.html CCivilian.h] for an example.
    237 
    238 = Standard Template Library =
     201== Standard Template Library ==
    239202
    240203We will make use of the Standard Template Library (STL). Although we may be capable of coding list, maps and queues ourselves and do so more efficiently. Our goal is to create a game not to recreate an existing library.
    241204
    242 Having said that I prefer to wrap up specific STL object in an effort to make the code more readable � see [http://code.wildfiregames.com/resources/development/CCivilian.h.html CCivilian.h] for an example.
    243 
    244 = Global variables or Singletons =
    245 
    246 Much debate regarding the use of global variables has been generated over the years so I will not re-enter that discussion. I will say that the Singleton design pattern does provide many benefits over that of a pure global variable.
    247 
    248 We will make use of the Automatic Singleton Utility as described by Scott Bilas in article 1.3 of the �Game Programming Gems�, volume I, �An Automatic Singleton Utility.�
    249 
    250 = Strings =
    251 
    252 A string class has been written, CStr, that should be used instead of directly using std::string or using C-style strings (i.e. char*).
     205Having said that, it may make sense to hide some uses of STL objects behind an interface. This can make the code more readable.
     206
     207== Singletons ==
     208
     209Much debate regarding the use of global variables has been generated over the years so we will not re-enter that discussion. The Singleton design pattern does provide many benefits over that of a pure global variable.
     210
     211We will make use of the Automatic Singleton Utility as described by Scott Bilas in article 1.3 of the "Game Programming Gems", volume I, "An Automatic Singleton Utility".
     212
     213== Strings ==
     214
     215A string class has been written, `CStr`, that should be used instead of directly using `std::string` or using C-style strings (i.e. `char*`).