Coding Style Guidelines

Coding Style Guidelines

<p> Coding Style Guidelines</p><p>Introduction</p><p>The purpose of standardizing a coding style for a development team or project is to reduce friction in the development process. What does it matter if we name our variables or indent our braces in one way or another? To the perspective of a modern compiler, it obviously does not matter. But more importantly, the discipline of a shared style increases overall efficiency, in terms of readability and understanding of the source code-- not only to teammates and other individuals that may need to understand, review, and debug and maintain others' works, but the author himself returning a year from now to update a project, would benefit. With the time saved from trying to get past unfamiliar styles to understand the intent of each other's source code, we can make more significant improvements to our programs. Now doesn't that sound more fun and rewarding?</p><p>It is the intent of this document to provide a guideline to a shared style for our C++ source code. Some of the guides may seem arbitrary, but it is more important to agree upon a single style rather than finesse from the diverse opinions. As a rule, when modifying code that doesn't fit the guidelines set in this document, please either match the different coding style of the function, or modify the entire function to the correct style. Finally, this document shouldn't be etched in stone. As opinions change and the team develops, this document should be periodically brought out and reviewed for changes in content and guidelines.</p><p>Please read and follow our guidelines, you will see the benefit. Thank you for being a good development citizen!</p><p>Naming Conventions</p><p>General Naming Conventions Prefix Examples</p><p>Classes C CELEventFrame, CSlide</p><p>Interfaces I IMediaControl</p><p>Methods Invalidate, OnMouseDown</p><p>Private Functions ApplyStyle, Draw</p><p>Data members m_ m_valid, m_idleCounter</p><p>Static data members s_ s_eventPump, s_topOfStack</p><p>Variables curSlp, ghostPat</p><p>Global variables g_ g_fOleInit, g_pTypeLib</p><p>Constants, Enumerations Package- prefix_ GR_STYLEPLAIN, TX_ALIGNLEFT, W_PANE_NOERASEBG</p><p>Type Prefix p Pointer to (32-bit is now assumed; thus no need for lp). pp Pointer to a pointer h Handle to, aka cookie or abstract pointer (illegal to dereference). ref Reference to (eg: when passing parameters by reference in C++). rg Array of (ie: items stored sequentially in memory). Note: rg is often used. z Terminated array of. sz CHAR *,String, C type (ie: array of 8-bit characters, null character terminated) or CString wsz WCHAR *, Unicode string.</p><p>1 tsz TCHAR *, Flexible Unicode/DBCS string. vec Vector mat Matrix</p><p>Type Indicator s SHORT Signed integer, 16-bit. l LONG Signed integer, 32-bit. us USHORT Unsigned integer, 16-bit. ul ULONG Unsigned integer, 32-bit. b BYTE Non-counting purposes, 8-bit allocation. w WORD Non-counting purposes, 16-bit allocation. dw DWORD Non-counting purposes, 32-bit allocation. i int Scalable signed integer u UINT Scalable unsigned integer fl float Floating point, 32-bit, 6-7 significant digits. d double Floating point, 64-bit, 15-16 signigicant digits. ch CHAR Character, 8-bit. wch WCHAR Character, Unicode, 16-bit. tch TCHAR Character, flexible Unicode or DBCS. fn Function Function: always used with a type prefix (eg: pfn is pointer to function). v void Void: always used with a type prefix (eg: pv is pointer to void). f bool or BOOL f means flag var VARIANT or variant_t</p><p>Certain abbreviations have become standard abbreviation Word src Source dst Destination rc Rectangle quad Quadrilateral pt Point tx Text ptr Pointer stat Status or state cmd Command id Identifier wnd Window btn Button sel Select or Selection</p><p>Member Function Names</p><p>We highly recommend using the following standard prefixes for member function names. Function prefix Type of function</p><p>F… Query operations that return a bool</p><p>2 Get… Gets a property.</p><p>Set… or Put… Sets a property.</p><p>Create… Creates or duplicates a C++ object. Use “Duplicate” for a method that duplicates the object Dup… itself. Objects returned by these functions must be disposed with delete.</p><p>On… Protected notification methods usually overridden by clients. Where both On and After After… methods are provided, On is called prior to the event, and After is called after.</p><p>Draw… Modifier operations (named with active verb phrases). Move…</p><p>Swap Swaps the contents of one object with the contents of another in a way guaranteed to succeed and not throw an exception.</p><p>Code formatting</p><p>Indentation</p><p>No Tab character</p><p>Make sure all tab character converted to 4 spaces.</p><p>Indent level</p><p>One indent level is 4 spaces</p><p>Indent data declarations and executable statements one level // Example of function definition PCOMMSG ComGetMsg( PCOMSERVER pServer, long lTimeOut) { //--- Data indented same level as code PCOMMSG pMsg;</p><p>//--- Code indented one level pMsg = ComReadMsgFromQueue( pServer, NULL, ComWait_c, lTimeOut ); if ( NULL == pMsg ) { ErrReport( “Server connection broken” ); } return pMsg; }</p><p>Indent function and data declarations at least one additional level beyond the public, protected, and private keywords. class CExample { //--- public, protected and private functions indented. public: //--- Member function declarations indented at least on additional level CExample(); ~CExample();</p><p>3 private: #ifdef _DEBUG void TraceValue( int iValue ); #endif</p><p>//--- public, protected and private data members indented. private:</p><p>//--- Data declarations indented one level int m_iStoreSomething; };</p><p>Indent long function calls pMsg = ComReadMsgFromQueue( aServer, NULL, ComWait_c, lTimeOut );</p><p>Brace </p><p>Use Braces "{}" to mark the beginning and end of all compound statement aligned vertically with their parent block. while (foo) { if (bar) { Yabba(dabba); } else { foo(); } Xyz(abc); }</p><p>Statements that have bodies should put those bodies on a separate line and braces should always be used – even if the body is only a single line. for( <iteration parameters> ) { <single line of real stuff> }</p><p> if ( <conditional expression> ) { <statement_1> }</p><p>4 else if ( <conditional expression> ) { <statement_2> } else { <statement_3> } </p><p>White Spaces and line breaks</p><p>The maximum line length is 80 characters</p><p>Leave at least one space between a binary operator and each of its operands; use extra spaces to align operands if this improves readability: iA = iB + iC; iMinimum = -iAmplitude; cLetter = *pChar; flY = ( flX * flSlope ) + flY0; x = ( pEvent->m_iButton == iButtonPress ) && ( 1 == pEvent->m_iButton );</p><p>Never end a line with a space or tab.</p><p>Have a blank line between variable declarations and code. BOOL FFoo(void) { BAR bar1, bar2; int cbar; // There is a blank line below.</p><p> cbar = Bar(&bar1, &bar2); return cbar == 0; }</p><p>Spaces are always AVOIDED in the following places:</p><p>Between the function name and the left parenthesis, e.g. “Foo (”</p><p>Between a pointer and the variable it modifies, e.g. “FOO * pfoo”</p><p>Next to arrows, e.g. “a-> b”;</p><p>Next to variable/dot combinations, e.g. “a. b”</p><p>Spaces are always USED in the following places:</p><p>Around keywords, e.g. “if (...)” and never “if(...)”.</p><p>Between argument/variable combinations in parentheses, e.g. “(a, b, c)”</p><p>Between a type and a pointer, e.g. “FOO *pfoo”</p><p>Surrounding equals signs, e.g. “a = b;” and never “a=b;”</p><p>5 In summary, spaces are placed as in English (e.g. space after comma, no space after parentheses, space after keywords, space before and after most operators).</p><p>Never have multiple statements on one line like a = 1; b = 2; // bogus if (fFoo) Bar(); // bogus</p><p>Labels are always on lines by themselves. LFoo: a = 1; // bogus</p><p>Syntax</p><p>Common Types</p><p>Use the built-in types (short, int, long, etc.).If it requires limit types used, it’s recommend to redefine all types used in a common header file.</p><p>Structs struct POINTD // use this { REAL X; REAL Y;</p><p>}; typedef struct tagPOINTD // Do not use this { REAL X; REAL Y;</p><p>} POINTD;</p><p>Const-correctness</p><p>Use const wherever an item won’t be changed. HRESULT Compress(BYTE *pbOut, DWORD *pbOutLen, const BYTE* pbSrc, const DWORD dwSrcLen);</p><p>Type casts</p><p>Use explicit typecast force compiler and programmer to more verification. int *ptr = (int *) malloc(xyz); // DON’T DO THIS char *device = (char *) 0xf0000123; // DON’T DO THIS int myInt = (int) myConstInt; // DON’T DO THIS</p><p>Use these: int *ptr = static_cast<int *>(malloc(xyz)); char *device = reinterpret_cast<char *>(0xf0000123); int myInt = const_cast<int>(myConstInt);</p><p>Function definitions</p><p>6 Must be defined with the return type VOID RandomObject::DoSomething( INT x, Blob *blob ) { blob->Glob(x); }</p><p>In function declarations (prototypes), the following is allowed if it fits on one line. INT ComputeArea(INT x, INT y);</p><p>Function calls</p><p>If the call fits on one line: answer = GetAnswer(x, joe, blob);</p><p>Otherwise, put each parameter on a separate line, indented one level: MyFunctionWithLongName( sqrt(x*x + y*y), *(ptr + 64) – 30 );</p><p>Comments (Clear and necessary)</p><p>You can simply copy and paste the following comments before file header and functions to your code.</p><p>File headers /*****************************************************************************\</p><p>Zhejiang University Copyright (c) 2004 Zhejiang University</p><p>Module Name:</p><p>An unabbreviated name for the module (not the filename)</p><p>Abstract:</p><p>Description of what this module does</p><p>Notes:</p><p>[Optional] Additional notes about this module - things that may help the reader of this code later on. Examples are: algorithm description, special case conditions, references, etc.</p><p>History:</p><p>7 Created on mm/dd/yyyy by email-name Modified on mm/dd/yyyy by email-name [Optional] history description</p><p>\*****************************************************************************/</p><p>Section separators //------… a commented one</p><p>//------// Buffer manipulation routines //------</p><p>Function headers /*****************************************************************************\</p><p>Function Description:</p><p>Description of what the function does</p><p>Arguments:</p><p>[<blank> | OUT | IN/OUT] argument-name - description of argument …</p><p>Return Value:</p><p> return-value - description of return value or NONE</p><p>History:</p><p>Created on mm/dd/yyyy by email-name</p><p>\*****************************************************************************/</p><p>Classes definition</p><p>Please follow this example:</p><p>#define IN // Nothing but a sign show the input/output parameters #define OUT class CMyClass {</p><p>8 public: DWORD Compress(OUT BYTE *pbDest, // recommend use “IN” and “OUT” OUT ULONG*puDstLen, // to indicate input and output parameters IN const BYTE *pbSrc, IN const ULONG uSrcLen );</p><p>// short inline function can be inside class decalration inline GetByte(const ULONG uIndex) { return m_pBuffer[uIndex]; }</p><p>// Recommend use reference parameters to get output instead of pointer HRESULT GetHeaderInfo( IMAGE_HEADER& refImgHdr ); private: IMAGE_HEADER m_ImgHdr; // Data members should never be public public: virtual HRESULT Display(); // Be careful with virtual functions </p><p>// const for function means member data is not modified. // highly recommended const VOID Dump();</p><p>// Recommend use the two stages initialization BOOL Init(); // HRESULT can return more status BOOL Free();</p><p>CMyClass(); ~CMyClass(); }</p><p>Source Code File Structure</p><p>Here is the general format of the source code file for a class implementation: file header #include directives (private to implementation) #defines (private to implementation) typedefs (private to implementation) global variables internal functions exported functions "methods" implementing messages class initialization routine main routine (in an app class)</p><p>Here is the general format of the source code file for a non-class implementation: file header</p><p>9 #include directives (private to implementation) #defines (private to implementation) typedefs (private to implementation) global variables internal functions exported functions</p><p>Implementation Issues</p><p>One time include in header files</p><p>Headers should be protected with #ifndef…#define…#endif blocks for inclusion safety.</p><p>Sample.h #ifndef _GDIPLUS_H #define _GDIPLUS_H … … #endif // _GDIPLUS_H</p><p>Or you can simply use #pragma once at the beginning of file</p><p>Function length</p><p>Functions should be fewer than 100 lines long unless structure or performance requires a longer function. In general functions should be even shorter, with sub-functions created as necessary.</p><p>Use of NULL as flag</p><p>1 - Explicitly put NULL in any value test: //Don’t do this: if (pInterface) { } // do this instead if (NULL != pInterface) { }</p><p>2 - Always initialize and reset the pointer to NULL. This ensures that you will never be accessing a stale pointer // don’t do this if (NULL != pInterface) { pInterface->Release(); } // do this if (NULL != pInterface)</p><p>10 { pInterface->Release(); pInterface = NULL; }</p><p>Parameter Validation</p><p>Every public interface method must validate input parameters. HRESULT Foo( PBYTE pbSrc ) { ASSERT( NULL != pbSrc ); ... }</p><p>// TODO & // REVIEW Indicator</p><p>// TODO & //REVIEW indicator is a mark in comment to show the work should be done or reviewed later. It’s a good habit remind yourself and other colleagues before shipping in team project. Before shipping, all the // TODO should be removed (the tasks should be done or change // TODO to // REIVIEW)</p><p>Format: // TODO [task owner][(writer)]: Task description</p><p>Examples: // TODO: cleanup … The following is BARNWL tells GANGCH write cleanup code later // TODO: GANGCH(BARNWL): cleanup</p><p>11 Coding Style Checklist</p><p>1 Classes</p><p>Declaration</p><p>1.1 Declare all class members explicitly as public, protected, or private, in groups in that order.</p><p>1.2 Do not declare public data members in classes. Use inline accessor functions for performance.</p><p>1.3 Virtual functions have overhead, so don’t use them unless you really should.</p><p>1.4 An overridden virtual method is explicitly declared virtual for clarity.</p><p>1.5 A destructor in a base class should always be virtual if polymorphism is intended.</p><p>1.6 Never hide expensive work behind an operator. If it’s not super efficient then make it an explicit method call.</p><p>1.7 Don’t use inheritance just because it will work. Use it sparingly and judiciously.</p><p>1.8 Don’t use multiple inheritance.</p><p>Constructor and Destructor</p><p>1.9 Never declare a global instance of a class that has a constructor.</p><p>1.10 Do not do expensive work in a constructor.</p><p>1.11 If you do make a constructor, make sure to initialize all data members.</p><p>1.12 A constructor should never fail. Do memory allocations and other potential failures in a FInit or Create method.</p><p>1.13 A destructor should never fail</p><p>2 Other C/C++ Issues</p><p>2.1 Avoid allocating class instances on the stack and passing them by value. Use new and delete, and pass them by</p><p> pointer.</p><p>2.2 If resources are freed before destruction, make sure the fields are reset (e.g. set pointers to NULL) to prevent multi-</p><p> free.</p><p>2.3 Use const or enum instead of #define for constants when possible.</p><p>2.4 Use const to mark read-only pointer parameters (what the pointer points at, not the pointer itself).</p><p>2.5 Don't use default arguments.</p><p>2.6 Minimize global variables.</p><p>2.7 Use inline functions instead of #define macros when possible</p><p>2.8 In functional macros, enclose all argument instances in parentheses “( )” as well as the entire expression if necessary.</p><p>2.9 Functions that return pointers but can fail should return a BOOL and return the pointer in a parameter.</p><p>2.10 DLL-exported data should be avoided, but must use extern "C" if needed.</p><p>2.11 Use the macros defined in OLE’s objbase.h where appropriate for C/C++ declarations, especially COM-style</p><p> interfaces.</p><p>3 Source File Organization</p><p>3.1 Filenames use prefix denoting the major feature team (e.g. “tb” for Toolbars), then <= 6 more characters.</p><p>12 3.2 Use one-time include in header file, e.g., #pragma once or #ifndef FOO_H, #define FOO_H , #endif //</p><p>FOO_H </p><p>4 Basic Data Types</p><p>4.1 Use the following common basic data types: void, int, BOOL, UINT, BYTE, CHAR, WCHAR, USHORT, WORD,</p><p>SHORT, ULONG, DWORD, LONG, HRESULT</p><p>4.2 Use other types already defined by Windows (e.g. RECT, POINT) when possible, especially in exported interfaces.</p><p>4.3 Use "BOOL", "int", or "UINT" in most bitfields, unless size is important, then use a size-specific type such as</p><p>USHORT.</p><p>4.4 Use flat 32-bit pointers everywhere (declared using just plain “*”).</p><p>5 Naming Conventions</p><p>5.1 Use Hungarian naming conventions. Invent new tags and use them consistently where appropriate to preserve</p><p> abstraction. </p><p>5.2 Check tags and prefixes defined in the tables of naming convention section</p><p>6 Formatting Issues</p><p>6.1 Each file starts with a standard file header comment</p><p>6.2 Make sure your editor indents using 4 space tabs.</p><p>6.3 Keep line length within 80 characters.</p><p>6.4 Indent correctly in declarations and statements including: function, class, switch and if</p><p>6.5 Place spaces as in English (after keywords and commas, not after open parentheses, between many operators).</p><p>6.6 Write comments necessary, simple and clear</p><p>6.7 Use a blank line between blocks of code separated by a summary comment.</p><p>6.8 Precede function prototypes with a comment describing the function in complete sentences, mentioning each</p><p> parameter.</p><p>6.9 Use “// TODO: comment” to mark incomplete code, and “// BUG: comment” to mark wrong code.</p><p>6.10 Check everything referring to code formatting</p><p>13</p>

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    13 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us