sipXecs编码标准

http://wiki.sipfoundry.org/download/attachments/4883124/sipXecs-cpp-coding-standards.html?version=1&modificationDate=1297549171000

http://wiki.sipfoundry.org/display/sipXecs/Coding+Standards

 

sipX Project Coding Standards for C, C++, and Java   

Actually, a language is characterized not so much by what it lets us    program as by what it keeps us from expressing.  As E.W. Dijkstra    observed, the programmer's most difficult, daily task is to not mess    things up.  The first and most noble duty of a language is thus to    help in this eternal struggle.  -- Niklaus Wirth

      Last Modified 2005-07-25 15:05:12-0400

    NOTE: These coding standards are derived    from the coding standards developed for the Vision 2000 CCS    project, Todd    Hoff's C++ coding standards, and AmbySoft's    Java coding standards.   

      A good developer knows that there is more to development than programming.
      A great developer knows that there is more to development than development.   
    Remember that you write code for three audiences:  The computer, for    whom it must be correct, your muse, for which it it must be elegant,    and the poor schmuck who has to modify it, for whom it must be    comprehensible.
-- Daniel R. Killoran   

      Introduction   

      The purpose of these coding standards is to facilitate the      maintenance, portability, and reuse of custom C, C++, and      Java source code developed by the sipX open source project. These standards were      developed from a variety of sources, including other      standards documents, software examples from defacto standard      language references, and personal experience. As with any      guidelines, there will be circumstances where full compliance      is not desirable for efficiency, maintainability, or other      reasons. In these cases, conformance should not be pursued      simply for the sake of meeting the standards.   

0.1      When the standards are not followed, it is advisable to add a      comment with the reason for non-conformance.   

1 File Organization
        Source file contents and layout.       
  • 1.0 File Contents
  • 1.1 Source File Layout
  • 1.2 Header File Layout
  • 1.3 Header File Guard
  • 1.4 Doxygen Documentation         
    • 1.4.1 Comment Style
    • 1.4.2 Comment Placement
    • 1.4.3 Class Documentation
    • 1.4.4 Member Grouping
    • 1.4.5 Member Function Documentation
    • 1.4.6 Examples
    • 1.4.7 Lists
2 Naming Conventions
        How to name files and identifiers.       
  • 2.1 Descriptive Names
  • 2.2 Valid Characters
  • 2.3 Prefixes and Suffixes
  • 2.4 Class Attribute Names
  • 2.5 File Names
  • 2.6 Function Names
  • 2.7 Namespaces
  • 2.8 Subversion Properties           
    • 2.8.1 svn:ignore
    • 2.8.2 svn:mime-type and svn:eol-style
    • 2.8.3 sf:tab
  • 2.9 strcasecmp and strncasecmp
3 Style Guidelines
        Guidelines for how source code should look.       
  • 3.1 Lines           
    • 3.1.1 Line Length
    • 3.1.2 Statements Per Line
    • 3.1.3 Final EOL
  • 3.2 Comments           
    • 3.2.1 Automated Documentation Comments
    • 3.2.2 Code Block Comments
    • 3.2.3 Blank Lines
  • 3.3 Formatting           
    • 3.3.1 Spacing Around Operators
    • 3.3.2 Indentation and Braces
    • 3.3.3 Pointer and Reference Position
  • 3.4 Statements           
    • 3.4.1 Control Statements
    • 3.4.2 Conditional Statements
    • 3.4.3 Include Statements
  • 3.5 Declarations           
    • 3.5.1 Variable Declaration
    • 3.5.2 External Variable Declaration
    • 3.5.3 Numeric Constant Declaration
    • 3.5.4 Enumerated Type Declaration
    • 3.5.5 Struct and Union Declaration
    • 3.5.6 Class Declaration
4 Recommended
  • 4.1 Placement of Declarations
  • 4.2 Switch Statements
  • 4.3 Return Statements
  • 4.4 Casts
  • 4.5 Literals
  • 4.6 Explicit Initialization
  • 4.7 Checking Error Returns
  • 4.8 Short Methods
  • 4.9 Document Null Statements
  • 4.10 Comments on Comments           
    • 4.10.1 Comments Should Tell a Story
    • 4.10.2 Document Decisions
    • 4.10.3 Make Gotchas Explicit
  • 4.11 Constructs to Avoid
  • 4.12 Macros
  • 4.13 Debug Compile-time Switch
  • 4.14 Memory Management
  • 4.15 Constructors
  • 4.16 Destructors
  • 4.17 Argument Passing
  • 4.18 Default Arguments
  • 4.19 Overriding Virtual Functions
  • 4.20 Const Member Functions
  • 4.21 Referencing Non-C++ Functions
  • 4.22 NULL Pointer
  • 4.23 Enumerated Types
  • 4.24 Terminating Stream Output
  • 4.25 Object Instantiation
  • 4.26 Encapsulation
  • 4.27 Default Constructor
  • 4.28 Importing Packages
  • 4.29 Exception Handling
5 Source Code Templates

1. File Organization   

1.0 File Contents   

      Files should be used to organize related code modules, either      at the class (for C++ and Java) or function (for C) level.      The following table identifies the contents of individual      files for each language:   

 

            File contents                      C                      C++                      Java         
            class declaration (header)                        n/a                        X                        n/a         
            class definition (source)                        n/a                        X                        X         
            main function                        X                        X                      (with primary class)         
            function(s)                        X                        X                        n/a         
            globals                        X                        X                        n/a         

1.1 Source File Layout   

      Source files should contain the following components in the      order shown. When creating new source files, developers      should use the appropriate template file as a starting point.   

 

            File contents                      C                      C++                      Java         
            prolog (incuding copyright)                        X                        X                        X         
            package imports                        n/a                        n/a                        X         
            system #includes                        X                        X                        n/a         
            application #includes                        X                        X                        n/a         
            external functions                        X                        X                        n/a         
            external variables                        X                        X                      n/a         
            constants                        X                        X                        X         
            static variable initializations                        X                        X                        X         
            class declaration                        n/a                        n/a                        X         
            public methods                        n/a                        X                        X         
              creators                        n/a                        X                        X         
              manipulators                        n/a                        X                        X         
              accessors                        n/a                        X                      X         
              inquiry                        n/a                        X                        X         
            protected methods                        n/a                        X                        X         
            private methods                        n/a                        X                        X         
              non-testing                        n/a                        X                        X         
              testing                        n/a                        X                        X         
            functions                        X                        X                        n/a         
(C, C++) When it is possible to put a        needed  #include line in the source file instead of in        the header file, do so.  This will reduce unnecessary        file dependencies and save a little compile time.     

1.2 Header File Layout   

      Header files should contain the following components in the      order shown (note that Java does not use header files). When      creating new header files, developers should use the      appropriate template file as a starting point.   

 

            File contents                      C                      C++                      Java         
            prolog (including copyright)                        X                        X                        n/a         
            file guard                        X                        X                        n/a         
            system #includes                        X                        X                      n/a         
            application #includes                        X                        X                        n/a         
            #defines                        X                        X                        n/a         
            macros                        X                        X                        n/a         
            external functions                        X                        X                        n/a         
            external variables                        X                        X                        n/a         
            constants                        X                        X                        n/a         
            structs                        X                        X                        n/a         
            forward declarations                        X                        X                        n/a         
            class declaration                        n/a                        X                        n/a         
            public methods                        n/a                        X                        n/a         
              creators                        n/a                        X                        X         
              manipulators                        n/a                        X                        X         
              accessors                        n/a                        X                        X         
              inquiry                        n/a                        X                        X         
            protected methods                        n/a                        X                        n/a         
            private methods                        n/a                        X                        n/a         
              non-testing                        n/a                        X                        X         
              testing                        n/a                        X                        X         
            inline method definitions                        n/a                        X                        n/a         
            functions                        X                        X                        n/a         
(C++) Small inline methods may be        implemented in the class definition.     

1.3 Header File Guard   

(C,C++) All header files should        contain a file guard mechanism to prevent multiple        inclusion. This mechanism is implemented as shown by the        following lines:     
   #ifndef _MeaningfulName_h_      // first line of the header file following the prolog
   #define _MeaningfulName_h_      // second line of the header file following the prolog
           .
           .                       // body of the header file
           .
   #endif  // _MeaningfulName_h_   // last line of the header file; note comment

1.4 Doxygen Documentation   

    C++ (and C) code uses the Doxygen system for    generating documentation from header and source files.  Doxygen    supports a wide range of styles; this section provides    recommendations for how it should be used in sipX projects.   

1.4.1 Comment Style   

    Doxygen comments are distinguished from normal comments by    an extra comment character at the beginning, and are associated    with the adjacent code by    their placement.  Both C style comments and C++ single-line style    comments are supported.   

C multiple-line style comments
Doxygen interprets any comment that has an extra '*'        character at the beginning of the comment:
        /** Doxygen single line comment */

        /**
        * Doxygen comment
        * that extends over more than one line
        * this form should be used whenever there is more than one line
        */
        
C++ single-line style comments
Doxygen interprets any C++ comment that has an extra '/'        character at the beginning of the comment:
        /// Doxygen single line comment
        
        Multiline comments composed of multiple C++ style comments are        not preferred:
        /// Doxygen comment
        /// that extends over more than one line
        

1.4.2 Comment Placement   

    Doxygen comments are, by default, associated with the code that    immediately follows the comment:   

    /// indicates whether or not the object currently allows any Foo actions.
    void isFooAllowed();
    

    For some constructs it is more readable to place the comment after    the code element it documents, which is accomplished by adding a    '<' character after the Doxygen comment indicator.  This may be    used with either single or multi-line comments:   

    void doFooAt( int offset, ///< the offset into the Foo
                  char* name  /**<
                               * the name to look up for this Foo action
                               * in the FooMgr database.
                               */
                );
    

      Placing the Doxygen comment after the element it documents in this      way is preferred whenever the element is a member of a list, as in      parameter declarations or enum values.   

1.4.3 Class Documentation   

    A class declaration must include a detailed description comment    preceeding the class:   

    /**
     * FooFactory is a factory class that constructs instances of the
     * subclasses of Foo based on information obtained from the
     * foo-config file.
     */
    class FooFactory
    {
    

    The class comment is a good place to put general guidelines about    how the methods in the class relate to one another.   

1.4.4 Member Grouping   

    By default, Doxygen groups the members within a class based on    heuristics that use the public/protected/private scope and the    method signatures.  For simple classes this usually works well,    and may be used.  When a class has many methods, it is usually    better to explicitly control how they are grouped in the    documentation, and to provide additional documentation at the    group level.  To explicitly control grouping, add the    'nosubgrouping' Doxygen command to the class comment:   

      /**
       * FooFactory is a factory class that constructs instances of the
       * subclasses of Foo based on information obtained from the
       * foo-config file.
       *
       * @nosubgrouping
       */
      class FooFactory
      {
    

      Each group is then formed of the following elements:     

  1. an introducing Doxygen comment that supplies the      group name using the 'name' Doxygen command,
  2. the detailed comment for the group,
  3. the Doxygen group start command '{',
  4. the declarations of the members in the group and      accompanying documentation, and finally
  5. the Doxygen group end command '}'.

      For example (preceeded      here by a non-Doxygen comment with a line of '=' characters so that      it reads better in the source file):   

     // ================================================================
     /** @name Searching
      *
      * The searching methods apply a compiled regular expression to a subject
      * string.  All searching methods return a boolean result indicating whether
      * or not some match was found in the subject.  To get information about
      * the match, use the Results methods.
      */
     ///@{

     ... the methods in the group ...

     ///@}
    

1.4.5 Member Function Documentation   

      Each member function should have:   

  • a brief single line description preceeding the member declaration,
  • parameter descriptions following each parameter, and
  • a more detailed description following the declaration, which      should include a Doxygen 'returns' command if the method returns a value.
      /// Search a string for matches to this regular expression.
      bool Search( const char * subject,  ///< the string to be searched for a match
                   int len = -1,          ///< the length of the subject string
                   int options = 0        ///< sum of any PCRE options flags
                   );
      /**<
       *    Apply the regular expression to the subject string.
       *    Optional parameter len can be used to pass the subject's length to
       *    Search(). If not specified (or less than 0), strlen() is used
       *    internally to determine the length. Parameter options can contain
       *    any combination of options; for options documentation, see 'man pcre'
       *    @returns true if a match is found.
       */
    

1.4.6 Examples   

      Including examples in the documentation is strongly encouraged.  To      embed an example, use the Doxygen "@code ... @endcode" construct:   

      /**<
       * May only be called after a successful search
       * and applies to the results of that call.
       * @returns true if there was an ith match, false if not
       *
       * Example:@code
       * RegEx matchBs("((B)B+)");
       * UtlString getB;
       * UtlString getBs;
       * if (matchB.Search("xxaBBBBcyy"))
       * {
       *   matchB.MatchString(&getBs,0);
       *   matchB.MatchString(&getB,2);
       * }
       * @endcode
       * would set the UtlStrings
       *  - getBs to "BBBB"
       *  - getB  to "B"
       */
    

1.4.7 Lists   

      Numbered and bulleted lists are supported in Doxygen comments using      simple indentation conventions:   

      /**<
       * A numbered list is created using '#' characters:
       *  # first numbered item
       *  # second numbered item
       *    # first item in nested numbered list (2.1)
       *
       * A bullet list uses '-' characters:
       *  - first bullet
       *  - second bullet
       *    - nested bullet
       */
    

2 Naming Conventions   

      The following table summarizes the naming conventions:   

 

            Identifier                      C                      C++                      Java         
            package                        n/a                        shortname         
            class, union, struct                        MeaningfulName         
            exception class                        n/a                        MeaningfulException         
            interface                        n/a                        MeaningfulActionable         
            typedef                        MeaningfulName, *MeaningfulNamePtr                        n/a         
            enum                        n/a                        MeaningfulName                        n/a         
            function, method                        PseudoClass_MeaningfulName                        meaningfulName         
            accessor method                        n/a                        getX, setX         
            inquiry method                          isX, hasX         
            object, variable, argument                        meaningfulName         
            class attribute                        n/a                        mMeaningfulName         
            pointer variables                        pMeaningfulName                        n/a         
            reference variable                        n/a                        rMeaningfulName                        n/a         
            global variable                        gMeaningfulName                        n/a         
            static variable                         sMeaningfulName         
            #define, macro                        MEANINGFUL_NAME                        n/a         
            const, static final variable                        MEANINGFUL_NAME         
            source file                        .c                        .cpp                        .java         
            header file                      .h                        n/a         

2.1 Descriptive Names   

      Names should be readable and self-documenting. Abbreviations      and contractions are discouraged. When confronted with a      situation where you could use an all uppercase abbreviation      instead use an initial upper case letter followed by all      lower case letters. Shorter synonyms are allowed when they      follow common usage within the domain.   

2.2 Valid Characters   

      All names should begin with a letter. Individual words in      compound names are differentiated by capitalizing the first      letter of each word as opposed to separating with an      underscore. The use of special characters (anything other      than letters and digits), including underscores is strongly      discouraged. The first 31 characters of a name (including the      prefix) must be unique, due to restrictions of various      platforms. The uniqueness must not be due solely to a      difference in case.   

2.3 Prefixes and Suffixes   

      Prefixes are sometimes useful:   

Is, Has - to ask a question about something.
        Whenever someone sees Is or Has they will        know it's a question     
Get - get a value
Set - set a value

      Suffixes are sometimes useful:   

Max - to mean the maximum value something can have     
Cnt - the current count of a running count variable     
Key - key value     

2.4 Class Attribute Names   

(C++, Java) All attribute names should        be prepended with the character 'm' in order to avoid any        conflict with method names.

(C++) The 'm' prefix always precedes        other name modifiers like 'p' for pointer or 'r' for        reference.     

2.5 File Names   

      Filenames should only contain one period, to separate the      file extension.   

2.6 Function Names   

      Function and method names should preferably begin with an      action verb. Boolean-valued functions (those that have two      possible return values) should use the "is" prefix as in      "isEmpty()".   

(C, C++) All functions must be        prototyped, with the prototypes residing in header files.     

2.7 Namespaces   

(C, C++) Libraries in danger of        conflicting with functions, classes or methods defined in        other libraries should choose some sort of unique prefix to        avoid name conflicts.       

(C++) The C++ namespace construct        should not be used. This construct is not yet widely        supported.       

(Java) Namespace collision should be        minimized without introducing cryptic naming conventions by        using the Java package construct. Create a new        Java package to group classes of related functionality.        Package source and class files then reside in a convenient        hierarchical directory structure that maps directly to the        package name.     

2.8 Subversion Properties   

2.8.1 svn:ignore

      A file that is generated in the course of building the software should      be listed in its containing directory's svn:ignore property.      This prevents it from being displayed by 'svn status'.      All files that 'svn status' reports as unknown (flags with '?') should      be files that the user/developer created manually.   

      More information on svn:ignore is in the Subversion book at http://svnbook.red-bean.com/en/1.1/ch07s02.html#svn-ch-7-sect-2.3.3.   

2.8.2svn:mime-type and svn:eol-style

      In order to ensure that files checked out from the repository      have the correct end-of-line characters for the platform onto      which they      are checked out, every file in the respository must      have the appropriate values for the Subversion properties svn:mime-type      and/or svn:eol-style.   

      All "binary" files in the repository should have a valid,      non-text MIME media type specified for      their svn:mime-type property.  (If no other type is suitable,      "application/octet-stream" can be used.)   

      All text files must have a "text/*" svn:mime-type property, and      an svn:eol-style property.      Most text files are relevant to all platforms, and should have      the value "native" for the svn:eol-style property.      This ensures that a Subversion checkout will use the right end-of-line      characters for the host operating system.   

      Text files that are specifically for use only on MS-Windows and similar      OS's should have an svn:eol-style property of "CRLF", so that they      can be checked out on other      OS's and made visible to MS-Windows systems (through shared      disks) without worrying about end-of-line translation.   

      Setting "automatic properties" in your Subversion configuration      can automate setting these properties in most cases.  A sample      Subversion configuration file      ($HOME/.subversion/config or      Application Data\Subversion\config) that works      for most of the file extensions used in sipX can be retrieved      here.      The list of officially-defined MIME media types is at http://www.iana.org/assignments/media-types.      SipX also uses WAV audio      files, which have no officially-defined MIME media type, but do      have a commonly understood extension type, audio/x-wav.      More information on svn:mime-type is at http://svnbook.red-bean.com/en/1.1/ch07s02.html#svn-ch-7-sect-2.3.2.      More information on svn:eol-style is at http://svnbook.red-bean.com/en/1.1/ch07s02.html#svn-ch-7-sect-2.3.5.      More information on configuring Subversion is at http://scm.sipfoundry.org/svndoc/ch07.html#svn-ch-7-sect-1.   

      There is a script in the developers' tool directory that will      check that a working copy is following these rules.  Commonly it      is run from the top directory of a working copy via:      sipXpbx/doc/developer/eol-check.sh sipX*

2.8.3 sf:tab

      Most text files in sipX projects should not contain tab      characters; they are allowed only when the file type      specifically requires them and no alternative is available; the      primary example of this is Makefiles.   

      Files which are exceptions to this rule can be marked by setting      the sf:tab Subversion property.      The value 'initial' can be set for files for which tabs are      allowed at the beginnings of lines.      The principal use for this value is "makefiles".  For this      reason, sf:tab = initial allows not only tabs at the beginnings      of lines, but also tabs preceded by '#' (for commenting out      lines).   

    The tab-check.sh script checks that all files with a text    MIME-type do not contain tab characters.   

      The value sf:tab = yes allows tabs in any location in a file.      This value should only be used on files imported from external      sources and files which require the use of tabs (e.g., some      Windows build control files).   

2.9 strcasecmp and strncasecmp

      The case-insensitive string comparison functions      strcasecmp and strncasecmp were      added to Posix relatively recently.  Many older Windows      development environments did not provide these functions, but      rather provided functions named      stricmp and strnicmp which provided      the same functionality with the same interface.      To avoid making each source file that needs these functions test      its environment, the include file os/OsDefs.h provides      #define's to convert strcasecmp and      strncasecmp into      stricmp and strnicmp when necessary.   

      Any file which needs to use this functionality must use the      names  strcasecmp and strncasecmp and must      #include os/OsDefs.h to ensure they are mapped if      the environment requires it.  (Certain files obtained from      third-party sources are exceptions to this rule.)   

3 Style Guidelines   

      The primary purpose of style guidelines is to facilitate      long-term maintenance. During maintenance, programmers who      are usually not the original authors are responsible for      understanding source code from a variety of applications.      Having a common presentation format reduces confusion and      speeds comprehension. Therefore, the following guidelines are      specified based on the principles of good programming      practice and readability. In the cases where two or more      equally valid alternatives are available, one was selected to      simplify specification. In the future, automated tools may be      used to apply style guidelines to source code files.   

3.1 Lines   

3.1.1 Line Length   

      Lines should not exceed 98 characters in order to display      without wrapping on an 100-character display. If wrapping is      required, try to break at an operator, and start the next      line with the operator vertically aligned. For example:   

    cout << "This is an example of a line which must be wrapped, value = "
         << value << endl;

3.1.2 Statements Per Line   

      Each statement should begin on a new line.   

3.1.3 Final EOL   

      In all text files, the final line should end with the appropriate      end-of-line characters (for the host operating system).      (Zero-length text files are acceptable, as they contain no lines.)   

3.2 Comments   

3.2.1 Automated Documentation Comments   

      For comments meant to be extracted by an automated      documentation tool, follow the Java convention of using the      standard C comment delimiters with an extra asterisk on the      first one, as shown:   

    /**
     * This is a module, class, function, or instance variable comment
     * that will be extracted by an automated documentation tool.
     */

      This will provide a consistent look across all source code      files, and should facilitate creation of automated      documentation tools.   

      Such comments should be used to describe classes, methods,      and global or instance variables.   

3.2.2 Code Block Comments   

      Code block comments should precede the block, be at the same      indentation level, and be separated by a blank line above and      below the comment. Brief comments regarding individual      statements may appear at the end of the same line, and should      be vertically aligned with other comments in the vicinity for      readability.   

(C) Code block comments should use the        standard C comment delimiters /* and        */.

(C++, Java) Code block comments should        use the single line comment delimiter //.     

3.2.3 Blank Lines   

      Use a single blank line to separate logical groups of code to      improve readability. In source files, use two blank lines to      separate each function.   

3.3 Formatting   

3.3.1 Spacing Around Operators   

      Spacing around operators and delimiters should be consistent.      In general, insert one space before or after each operator to      improve readability.   

  •         Do not use spaces inside of the parentheses around the        argument list.     
  •         Do not use a space within empty argument lists ()        or non-dimensioned arrays [].     
  •         Do not use spaces around the member access operators        . and ->.     
  • (C++) Do not use spaces around the        scope operator ::.     
        if (value == 0){                // right    
        if ( value == 0 ) {             // not recommended    
        void doIt(int v);               // right
        void doIt( int v );             // not recommended
        value = object->GetValue();     // right
        value=object -> GetValue();     // wrong

3.3.2 Indentation and Braces   

      The contents of all code blocks should be indented to improve      readability. Indent using 3 (recommended), 4, or 8 spaces for      each level. Do not use tabs, use spaces. Most      editors can substitute spaces for tabs.  See also the      sf:tab Subversion property.   

      Of the three major brace styles, two are acceptable - with the      first one listed being preferable.  For existing files, be      consistent with the brace style already in use in the file -      Do no mix styles within a file.

  •         Place brace under and inline with keywords:     
        if (condition)    if (condition)          while (condition)   int main()
        {                 {                       {                   {
           . . .             . . .                   . . .               . . .
        }                 }                       }                   }
                          else if (condition)
                          {
                             . . .
                          }
                          else
                          {
                             . . .
                          }

        struct MyStruct
        {
           int x;
           int y;
        }
  •         Traditional Unix policy of placing the initial brace on the        same line as the keyword and the trailing brace on its own        line and inline with the keyword. An exception is made for        method and function definitions where the initial brace is        handled as in the first style.     
        if (condition) {    if (condition) {         while (condition) {    int main()
           . . .               . . .                    . . .               {
        }                   }                        }                         . . .
                            else if (condition) {                           }
                               . . .
                            }
                            else {
                               . . .
                            }

        struct MyStruct {
           int x;
           int y;
        }

3.3.3 Pointer and Reference Position   

(C, C++) All declarations of pointer        or reference variables and function arguments should have        the dereference operator * and the address-of        operator & placed adjacent to the type, not        the variable. For example:     
   char*   text;                   // right
   char    *text;                  // not recommended
   char*   doSomething(int* x);    // right
   char    *doSomething(int *x);   // not recommended
    

3.4 Statements   

3.4.1 Control Statements   

      All control statements should be followed by an indented code      block enclosed with braces, even if it only contains one      statement. This makes the code consistent and allows the      block to be easily expanded in the future. For example:   

   if (value == 0)                     // right
   {
      doSomething();
   }
   if (value == 0) doSomething();      // wrong - no block, not indented

   if (value == 0)
      doSomething();                   // wrong - no block
    

3.4.2 Conditional Statements   

      Conditional statements found in if, while,      and do statements should be explicit based on the      data type of the variable being tested. For example:   

(C,C++)

   int value = getValue();
   if (value == 0)                    // right
   {
      doSomething();
   }
   if (!value)                        // wrong - not explicit test
   {
      doSomethingElse();
   }
   bool value = getValue();           // could be RWBoolean too.

   if (!value)                        // right
   {
      doSomethingElse();
   }

(Java)

   boolean value = getValue();
   if (!value)
   {                                  // right - this is explicit
      doSomethingElse();              // test for boolean type
   }

3.4.3 Include Statements   

(C,C++) For both source and header        files, #include statements should be grouped        together at the top of the file after the prolog. Includes        should be logically grouped together, with the groups        separated by a blank line. System includes should use the        < file.h> notation, and all other includes        should use the "file.h" notation. Path names        should never be explicitly used in #include        statements (with the exception of vendor library files such        as Motif), since this is inherently non-portable. For        example:     
   #include <stdlib.h>                     // right
   #include <stdio.h>                      //
   #include <Xm/Xm.h>                      //
   #include "meaningfulname.h"                   //
   #include "/proj/util/MeaningfulName.h"  // wrong - explicit path,
   #include <stdlib.h>                     //  out of order,
   #include </usr/include/stdio.h>         //  path for system file,
   #include "Xm/Xm.h"                      //  local include of library file

3.5 Declarations   

3.5.1 Variable Declaration   

      Each variable should be individually declared on a separate      line. Variables may be grouped by type, with groups separated      by a blank line. Variable names should be aligned vertically      for readability. There is no required ordering of types,      however some platforms will give optimal performance if      declarations are ordered from largest to smallest (e.g.,      double, int, short, char).   

   int*    a;              // right
   int     b;              //
   int     c;              //
   double  d;              //
   double  e;              //

   double  a;              // right
   int     b;              //

   double  d;              // acceptable - not grouped by type
   int     b;              //
   int*    a;              //
   double  e;              //
   int     c;              //
   int*    a, b, c;        // wrong - not individually declared, not
                           // on separate lines

   int*    a,              // wrong - not individually declared
           b,              //
           c;              //

      The two preceding examples are prone to error; notice that      a is declared as a pointer to integer and b      and c are declared as integers, not as pointers to      integers.   

3.5.2 External Variable Declaration   

(C,C++) All external variables should        be placed in header files. In general the use of global        variables is discouraged. Use the following method to allow        external variables to be created only once while using a        single declaration. In the header file which declares the        global variable, use a flag to cause the default        action on inclusion to be referencing of an externally        created variable. Only in the source file that wants to        actually create the variable will this flag be        defined.

         In the header file meaningfulname.h,     
   #ifdef MeaningfulNameInit     // the flag is called MeaningfulNameInit
   #define EXTERN                // create the variable (only in main.cpp)
   #else
   #define EXTERN extern         // just a reference (default)
   #endif
   EXTERN ErrorLogger errorLog;
   #undef EXTERN
        All of the source files should include this header file        normally:     
     #include "meaningfulname.h"
        while the following should appear only in the source        file where you actually want to declare the variable and        allocate memory for it (typically in main.cpp):     
   #define MeaningfulNameInit
   #include "meaningfulmame.h"
   #undef MeaningfulNameInit

3.5.3 Numeric Constant Declaration   

      Use only the uppercase suffixes (e.g., L, X, U, E, F) when      defining numeric constants. For example:   

   const int    value  = A73B2X;   // right, hexadecimal constant
   const double evalue = 1.2E9;    // right, scientific notation constant
   const float  fvalue = 1.2e9;    // wrong, lowercase e

3.5.4 Enumerated Type Declaration   

(C++) The enum type name and        enumerated constants should each reside on a separate line.        Constants and comments should be aligned vertically. The        following is an example of a valid enum        declaration:     
   enum CompassPoints
   {                  // Enums used to specify direction.
      North = 0,      //
      South = 1,      //
      East  = 2,      //
      West  = 3       //
   };
         (C++) It's often useful to be able to say an        enum is not in any of its valid states. Make a label for an        unitialized or error state. Make it the first label if        possible.     
   enum States
   {
      STATE_ERR,
      STATE_OPEN,
      STATE_RUNNING,
      STATE_DYING
   };

3.5.5 Struct and Union Declaration   

(C,C++) The struct type name        and structure members should each reside on a separate        line. This format separates the members for easy reading,        is easy to comment, and eliminates line wrapping for large        numbers of members. Each struct should have a        one-line description on the same line as the type name.        Each member should have a comment describing what it is,        and units if applicable. Members and comments should be        aligned vertically. Following is an example of a valid        struct declaration:     
   struct MeaningfulName      // This is a struct of some data.
   {
      int     firstInteger;   // This is the first int.
      int     secondInteger;  // This is the second int.
      double  firstDouble;    // This is the first double.
      double  secondDouble;   // This is the second double.
   };

3.5.6 Class Declaration   

(C++,Java) All class definitions        should include a default constructor, (virtual) destructor,        copy constructor and operator=.   If the class        has a pointer, provide a deep copy constructor (i.e.,        allocates memory and copies the object being pointed to,        not just maintains a pointer to the original object).         If any of these four are not currently needed, create stub        versions and place in the private section so they will not        be automatically generated, then accidentally used.         (This protects from core dumps.)  All classes should        have public, protected, and private access sections        declared, in this order. Friend declarations should appear        before the public section. All member variables should be        either protected or private. It is recommended that        definitions of inline functions follow the class        declaration, although trivial inline functions (e.g.,        {} or { return x; }) may be defined        within the declaration itself. Each member function and        variable should be commented using the automated        documentation comment delimiter //:. Member        functions should be commented in the same fashion as a        regular function. Member variables should each have a one        line description. Members and comments should be aligned        vertically. For example:     
   class Value : public BaseValue
   {
   public:
      Value();                        //: Default constructor.
      Value(const Value& oldValue);   //: Copy constructor.
      ~Value();                       //: Destructor.
      void setValue(int newValue);    //: Set value.
      int getValue();                 //: Get value.

   protected:
      void incrementValue();          //: Increment value.

   private:
      int value;                      //: The value.
   };

4 Recommended      Programming Practices   

4.1 Placement of Declarations   

      Local variables can be declared at the start of the function,      at the start of a conditional block, or at the point of first      use. However, declaring within a conditional block or at the      point of first use may yield a performance advantage, since      memory allocation, constructors, or class loading will not be      performed at all if those statements are not reached.   

4.2 Switch Statements   

      Specify a break statement after every case block,      including the last one unless multiple labels are used for      one selection of code.  It is recommended that a      default case always be defined.   

4.3 Return Statements   

      Where practical, have only one return from a      function or method as the last statement. Otherwise, minimize      the number of returns. Possibly highlight returns with      comments and/or blank lines to keep them from being lost in      other code.  Multiple returns are generally not needed      except for reducing complexity for error conditions or other      exceptional conditions.   

4.4 Casts   

      Avoid the use of casts except where unavoidable, since this      can introduce run-time bugs by defeating compiler      type-checking. Working with third-party libraries (e.g., X or      Motif) often requires the use of casts.  When you need      to cast, document the reasons.   

4.5 Literals   

      Use constants instead of literal values wherever possible.      For example:   

   const double PI = 3.141259;                     // right
   const char APP_NAME = "ACME Spreadsheet 1.0";   // right
   area = 3.141259 * radius * radius;              // not recommended
   cout << "ACME Spreadsheet 1.0" << endl;         // not recommended

4.6 Explicit Initialization   

      In general, explicitly initialize all variables before use.   

      It is very strongly recommended that you initialize all      pointers either to 0 or to an object.  Do not allow a      pointer to have garbage in it or an address in it, that will      no longer be used.   

4.7 Checking Error Returns   

      Include the system error text for every system error message.   

(C, C++) Check every system call for        an error return, unless you know you wish to ignore errors.        For example, printf returns an error code but rarely        would you check for its return code. In which case you can        cast the return to (void) if you really care.       

(C, C++) Check every          call to malloc or realloc unless you know your versions          of these calls do the right thing.       

4.8 Short Methods   

      Methods should not be longer than a single page of code.   

4.9 Document Null Statements   

      Always document a null body for a while statement so that it      is clear that the null body is intentional and not missing      code.   

4.10 Comments on Comments   

4.10.1 Comments Should Tell a Story   

      Consider your comments a story describing the system. Expect      your comments to be extracted by a robot and formed into a      man page. Class comments are one part of the story, method      signature comments are another part of the story, method      arguments another part, and method implementation yet another      part. All these parts should weave together and inform      someone else at another point of time just exactly what you      did and why.   

4.10.2 Document Decisions   

      Comments should document decisions. At every point where you      had a choice of what to do place a comment describing which      choice you made and why. Archaeologists will find this the      most useful information.   

4.10.3 Make Gotchas Explicit   

      Explicitly comment variables changed out of the normal      control flow or other code likely to break during      maintenance. Embedded keywords are used to point out issues      and potential problems. Consider a robot will parse your      comments looking for keywords, stripping them out, and making      a report so people can make a special effort where needed.   

Gotcha Keywords

:TODO: topic
      Means there's more to do here, don't forget.     
:BUG: [bugid] topic
        Means there's a known bug here, explain it and optionally        give a bug ID.     
:KLUDGE:
          When you've done something ugly say so and explain how you          would do it differently next time if you had more time.     
:TRICKY:
          Tells somebody that the following code is very tricky so          don't go changing it without thinking.     
:WARNING:
          Beware of something.     
:COMPILER:
          Sometimes you need to work around a compiler problem.          Document it. The problem may go away eventually.     
:ATTRIBUTE: value
                  The general form of an attribute embedded in a comment.                  You can make up your own attributes and they'll be                  extracted.     
      Gotcha Formatting   
  •         Make the gotcha keyword the first symbol in the comment.     
  •         Comments may consist of multiple lines, but the first line        should be a self-contained, meaningful summary.     
  •         The writer's name and the date of the remark should be part        of the comment. This information is in the source        repository, but it can take quite a while to figure out        when and by whom it was added. Often gotchas stick around        longer than they should. Embedding date information allows        other programmers to make this decision. Embedding the        author information let's us know whom to ask.     
      Example   
   // :TODO: tmh 960810: possible performance problem
   // We should really use a hash table here but for now we'll
   // use a linear search.

   // :KLUDGE: tmh 960810: possible unsafe type cast
   // We need a cast here to recover the derived type. It should
   // probably user a virtual method or template.

4.11 Constructs to Avoid   

(C, C++) The use of #define        constants is strongly discouraged, using const is        recommended instead.

(C, C++) The use of #define        macros is strongly discouraged, using inline        functions is recommended instead.

(C, C++) The use of typedef        is discouraged when actual types such as class,        struct, or enum would be a better        choice.

(C, C++) The use of extern        (e.g., global) variables is strongly discouraged. The        exception is for programs which benefit from having a small        number of object pointers accessible globally via        extern. The use of goto statements is not        allowed.     

4.12 Macros   

(C, C++) In a         macro definition, to eliminate ambiguity on expansion, all         uses of arguments should be enclosed in         parentheses and the entire macro expansion should be enclosed         in parentheses.         For example:     
   #define MAX(x, y)   (((x) > (y)) ? (x) : (y))

4.13 Debug Compile-time Switch   

(C,C++) Code used only during        development for debugging, testing or performance        monitoring should be conditionally compiled using        #ifdef compile-time switches. The symbols to use        are DEBUG, TEST and STATS, respectively.        Debug statements announcing entry into a function or member        function should provide the entire function name including        the class. For example:     
   #ifdef DEBUG
       cout << "MeaningfulName::doSomething: about to do something" << endl;
   #endif

4.14 Memory Management   

(C++) Use new and        delete instead of malloc/calloc/realloc        and free. Allocate memory with new only        when necessary for variable to remain after leaving the        current scope. Use the delete [] operator to        deallocate arrays (the use of delete without the        array operator to delete arrays is undefined). After        deletion, set the pointer to zero, to safeguard possible        future calls to delete. C++ guarantees that        delete 0 will be harmless.     

4.15 Constructors   

(C++) All constructors should        initialize all member variables to a known state. This        implies that all classes should have a default constructor        (i.e., MyClass();) defined. Providing a deep copy        constructor is strongly recommended.  If the        programmer wishes to not fully implement a copy        constructor, then a stub copy constructor should be written        and placed in the private section so no one will        accidentally call it.     

4.16 Destructors   

(C++) All classes which allocate        resources which are not automatically freed (e.g., have        pointer variables) should have a destructor which        explicitly frees the resources. Since any class may someday        be used as a base class, destructors should be declared        virtual, even if empty.     

4.17 Argument Passing   

(C++) If the argument is small and        will not be modified, use the default pass by value. If the        argument is large and will not be modified, pass by        const reference. If the argument will be modified,        pass by reference. For example:     
   void A::function(int notChanged);               // default: pass by value

   void B::function(const C& bigReadOnlyObject)    // pass by const reference

   void C::function(int notChanged, int& result);  // pass by reference

4.18 Default Arguments   

(C++) Where possible, use default        arguments instead of function overloading to reduce code        duplication and complexity.     

4.19 Overriding Virtual Functions   

(C++) When overriding virtual        functions in a new subclass, explicitly declare the        functions virtual. Although not required by the compiler,        this aids maintainability by making clear that the function        is virtual without having to refer to the base class header        file.     

4.20 Const Member Functions   

(C++) It is recommended that all        member functions (example:  func(...) const {...})        which do not modify the member variables of an object be        declared const. This allows these functions to be        called for objects which were either declared as        const or passed as const arguments.

(C++) It is recommended that all        member function parameters be declared const        (example:  func(const int i){...}) when possible.     

4.21 Referencing Non-C++ Functions   

(C++) Use the extern "C"        mechanism to allow access to non-C++ (not just C)        functions. This mechanism disables C++ name mangling, which        allows the linker to resolve the function references. For        example:     
   extern "C"
   {
      void aFunction();           // single non-C++ function prototype
   }

   extern "C"
   {
   #include "functions.h"          // library of non-C++ functions
   }

4.22 NULL Pointer   

(C++) Use the number zero (0) instead        of the NULL macro for initialization, assignment,        and comparison of pointers. The use of NULL is not        portable, since different environments may define it to be        something other than zero (e.g., (char*)0).     

4.23 Enumerated Types   

(C++) Use enumerated types instead of        numeric codes. Enumerations improve robustness by allowing        the compiler to perform type-checking, and are more        readable and maintainable.     

4.24 Terminating Stream Output   

(C++) Use the iostream manipulator        endl to terminate an output line, instead of the        newline character \n. In addition to being more        readable, the endl manipulator not only inserts a        newline character but also flushes the output buffer.     

4.25 Object Instantiation   

(C++, Java) Where possible, move        object declarations and instantiations out of loops, using        assignment to change the state of the object at each        iteration. This minimizes overhead due to memory allocation        from the heap.     

4.26 Encapsulation   

(C++, Java) Instance variables of a        class should not be declared public. Open access        to internal variables exposes structure and does not allow        methods to assume values are valid.

(C++) Putting variables in the        private section is preferable over the protected section,        for more complete encapsulation.  Use get and set        methods in either protected or public if needed.     

4.27 Default Constructor   

(Java) Where possible, define a        default constructor (with no arguments) so that objects can        be created dynamically using Class.newInstance().        This exploits the power of Java to dynamically link in        functionality that was not present at compile time.     

4.28 Importing Packages   

(Java) Use full package names instead        of wildcards when importing to improve comprehensibility        and provide context.     

4.29 Exception Handling   

(C++) In general, avoid        exception handling.  It is sometimes needed for third        party code, but in general, use return values        instead.  If you need it, document the reason for        using it.

5    Source Code Templates   

  • C++ Header File
  • C++ Source File

 

      Additional Coding Standards and Style Guides   

      For additional background and suggestions, there are a number      of coding standard documents available on the Web; these are      included for reference only and are not a part of this standard:   

  • Todd Hoff's C++        Coding Standards
  •         Recommended C Style and Coding Standards (Revised Indian        Hill)
  • Programming        in C++, Rules and Recommendations (Ellemtel)
  • Doug        Lea's Draft Java Coding Standard
  • AmbySoft        Inc.'s Java Coding Standard
  •         JavaSoft Coding Standards
  •         Netscape Coding Standards

 

你可能感兴趣的:(subversion,documentation,Comments,methods,Standards,variables)