VGDC Programming Guidelines

last modified by Hieu Le 9/28/2002
key contact: Hieu Le

1. Source Files

This section describes source file conventions.

Copyright, Description, History...

Include the following at the top of every file:

/**
* $Id$
* Description:
* This file contains implementation for math class.
*
*
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA, or go to
* http://www.gnu.org/copyleft/gpl.html.
*
*
*
* 03/01/00 XXX Package completed.
* 03/08/00 XXX Fixed a bug where negative numbers were not
* rounding correctly.
*
*/

Headers

To avoid multiple inclusions of the contents of a header, each header should begin with a #ifndef that tests whether some preprocessor symbol has already been defined, and should end with #endif. The preprocessor symbol should be the file name in all uppercase without the extension.surrounded by single underscore followed by the extension.

CGMetry.h 	--> CGMETRY_H
CWindow.h --> CWINDOW_H
CResType.r --> CRESTYPE_R

Each header should #include any prerequisite header files.

file CClass.h:

#ifndef CCLASS_H
#define CCLASS_H
.
.
#include "Prerequisite1.h"
#include "Prerequisite2.h"
.
.
#endif

 

File Names

File names no longer need to be in eight dot three format, but should contain no spaces or underscores. For compatibility with older platforms, they should be no longer than 31 characters. For future compatibility, assume case sensitive file names. Use the .cpp extension for all C++ source files. Use .c extension for all C source files.Use .h extension for all C/C++ header files.

LaySupp.h, LaySupp.cpp, Main.cpp

 

Comments

Classes, structs, enums, and typedefs should have the following comment format:

//===========================================================================================
// CLASS: CRegRootKey
//
// DESCRIPTION: Root key for CPrefDB. Root key maintains free lists for keys and values.
// There can only be one root key for a database, and root key cannot have values.
//===========================================================================================

Methods and routines should have the following comment format:

//-------------------------------------------------------------------------------------------
// CPrefDB::GetKeyValueHandle
//
// Retrieves the data associated with the given <key> and name, <valueName>. <data> must be
// preallocated with the minimum size of zero. Returns true if the value exists in the
// database, otherwise false.
//
// Pre: List any conditions that must exist before the function is called. This will be the
// basis for various assertions. May be omitted if there aren't any prerequisites
// or assumptions.
//
// Post: List the program condition after the function has been executed. May be omitted if
// it doesn't modify the program environment.
//-------------------------------------------------------------------------------------------

Source files should be logically divided into sections. To comment a section the following format should be used:

/////////////////////////////////////////////////////////////////////////////////////////////
// Include Files
/////////////////////////////////////////////////////////////////////////////////////////////

Disabling a section

If you need to temporarily disable a section of the code, don't comment it out. Instead, use <#if 0>, <#endif> pairs. This way, you can search your source for all the <#if 0> lines and re-enable them at a later time.

#include "foo.h"
#include "bar.h"

// Bad way to disable the section
// #define FOO 3.14
// #define BAR 5.5

// Good way to disable the section
#if 0
#define FOO 3.14
#define BAR 5.5
#endif


Newline at end of file

All files should end with a newline or certain compilers will crash or hang.

2. Naming Conventions

This section describes naming conventions.

Application

All classes should begin with a C for "class".

CGraphicObject, CBrowse, CCmd

All constants and enumerations should begin with a "k".

kAborted, kReturnCode, kEscapeCode, kSortDialogID

 

Local Variables and Function Arguments

Names of local variables and function arguments should begin witha word whose initial letter is lower case.

thePort, done, errCode, theWindow

 

Preprocessor Symbols and Macros

Preprocessor symbols and macros should be all capitalized.

CATCH(), THROW(), CWIN, DEBUG

 

Class Data Members

Class data members should begin with an m_ for "member". The first letter or word following the underscore should begin in lower case and should indicate something about the type of the member.

m_nLeft, m_bInForeground, m_pNext, m_bSelected

 

Globals and Statics

All global variables should begin with a g_ for "global". The first letter or word following the underscore should begin in lower case and should indicate something about the type of the member.

g_bBlack, g_bSolid, g_pEnvirons, g_pWindowList, g_pCmdQueue

 

All static variables should begin with a s_ for "static".

s_structInfo, s_fontTable

 

All static class members should begin with fs_ for "field static".

fs_Counter, fs_FontCount

 

Functions and Methods

Functions and methods should begin with a capital letter.

Select(), IsLocked(), QTENew(), Offset()

 

Multiple-word Names

In any name that contains more than one word, the first word should follow the convention for the type of the name, and subsequent words should immediately follow, with the first letter of each word capitalized. Do not use underscores in names.

CMenuBar, CGraphicObject, kNoErr, thePort, gWindowList, fInForeground

 

Note Since preprocessor symbols and macros are all capitalized, underscore should be used to separate words.(CMD_PREFERENCES, DECLARE_DYNINFO)

 

Accessors/Mutators

Accessor functions should begin with "Get", and mutator functions should begin with "Set".

HWND GetHWND();
void SetHWND(HWND w);

 

Note Sometimes it is redundant to prefix accessors/mutators. For example, rectangle class may have an accessor function called GetLeft() and a mutator function called SetLeft(). It would be more natural to have accessor/mutator functions called Left(). It will be left up to the engineer to follow either of the conventions.

3. Style

This section concerns coding style issues.

No spaces after function names

The left parenthesis should always be directly after the function name. This makes it much easier to find function calls (for reading and maintenance) when variables with similar names exist.

void foo ();			// No!
void foo(); // Better

 

Use empty blocks

The flow control primitives, if, else, while, for, and do shouldbe followed by a block, even if it is an empty block. At times, everything that is to be done in a loop may be easily written on oneline in the loop statement itself. It may then be tempting to conclude the statement with a semicolon at the end of the line. Thismay lead to misinterpretations since it is easy to miss such a semicolon. In such cases, it is better to place an empty block after the statement to clarify what the code is doing.

// no block at all, no!
while (doSomething) ; 

// semi-colon on next line with comment, better!
while (doSomething)
; // empty 

// empty block, good!
while (doSomething)
{
// empty
}

 

No spaces around unary operators

Do not use spaces around . or -> nor between unary operators and operands. Code is more readable if spaces are not used around the. or -> operators. The same applies to unary operators (those that operate on one operand), since a space may give the impression that the unary operand is actually a binary operator.

 

Put braces on lines by themselves

For ease of reading and maintenance, start and end blocks with braces on lines by themselves. Align the braces under the start of the keyword.

void *CSinglePtrList::RemoveAt(CPOSITION position)
{
CSinglePtrListNode *pOldNode = (CSinglePtrListNode*) position;

// remove pOldNode from list
if (pOldNode == mNodeHead)
{
mNodeHead = pOldNode->pNext;
}
else
{
CSinglePtrListNode *pTest = mNodeHead;
while (pTest != NULL && pTest->pNext != (CSinglePtrListNode*)position)
{
pTest = pTest->pNext;
}
if (pTest != NULL)
{
pTest->pNext = ((CSinglePtrListNode*)position)->pNext;
}
}

mCount--;
ASSERT(VerifyCount());

void *returnValue = pOldNode->data;
delete pOldNode;
return returnValue;
}

4. C/C++

This section describes coding conventions specific to use of C and C++.

Using C with C++

If you must use C with C++ and don't want to compile it under C++, don't forget to use the extern "C" wrapper for linkage of names.

#ifdef __cplusplus
extern "C"
{
#endif
void Foo();
void Bar();
#ifdef __cplusplus
}
#endif

 

Unspecified Arguments

Avoid using unspecified arguments since the arguments will not be type-checked. Instead use default arguments or function overloading.

void BadProc(char *ch, ...);

 

Compiler Specific Features

Do not use any compiler specific features.

asm, pascal, inherited

 

Constants

Avoid using #define to declare constants, instead use const or enum.

#define kTableSize = 10				// Bad!
enum {kTableSize = 10}; // Good! 
#define kWindowTitle = "UCI VGDC" // Bad!
const char *kWindowTitle = "UCI VGDC" // Good!

 

Inlines

Do not write the inline function definition directly in the class declaration. Always declare the function normally and then put an inline function definition in the source file (.cpp). A member function that is defined within a class definition automatically becomes inline. Class definitions are less compact and more difficult to read when they include definitions of member functions. It is easer for an inline member function to become an ordinary member function if the definition of the inline function is placed outside of the class definition.

class CFoo
{
public:
short BadInline() {return 1;}
short GoodInline();
};

inline short CFoo::GoodInline()
{
return 1;
}

Classes

The public, protected, and private sections of a class are to be declared in that order (the public section is declared before the protected section which is declared before the private section) By placing the public section first, everything that is of interest to a user is gathered in the beginning of the class definition. The protected section may be of interest to designers when considering inheriting from the class. The private section contains details that should have the least general interest. Typedefs, enums, methods, and data members are to be declared in that order.

class CFoo : CDynObj
{
// -- typedefs:
private:
typedef PARENT;
// -- enums:
public:
enum
{ kBarSize = 10; }
protected:
enum {kBufferSize = 255;}

// -- methods:
public:
CFoo();
virtual ~CFoo();
protected:
virtual void OnDraw();
privileged:
CBar *GetBar();
void SetBar(CBar *bar);
private:
int IsBar() const;
// -- data members:
protected:
int m_bar;
int m_foo;
private:
int m_size;
};

 

Friends

Friends of a class should be used to provide additional functions that are best kept outside of the class. Operations on an object are sometimes provided by a collection of classes and functions. A friend is a nonmember of a class that has access to the nonpublic members of the class. Friends offer an orderly way of getting around data encapsulation for a class. A friend class can be advantageously used to provide functions which require data that is not normally needed by the class. Friends are good if used properly. However, the use of many friends can indicate that the modularity of the system is poor.

 

const Member Functions

A member function that does not affect the state of an object is to be declared const. Member functions declared const may not modify member data and are the only functions which may be invoked on a const object. A const method declaration ensures that objects will not be modified.

5. Misc

Documentation

All documentations must be written in .html format. You can use the mozilla composer for all of your documentation needs. Just be sure to check the "Retain original source formatting" option in the Edit->Preferences menu before you start writing your documentation.

Directory Structure

Every projects should have the following directory structure:

/<projectname>/data            (optional)
/<projectname>/doc
/<projectname>/include
/<projectname>/res              (optional)
/<projectname>/src

You should keep all of your documentations in the /<projectname>/doc directory. But you may include a <README> file at the root directory if there are any special instructions that you want to tell the user.

CVS

If you edit your source files under Windows, use the Windows CVS client to check in your code. The same goes for Mac and Unix systems. UNDER NO CIRCUMSTANCES should you use a different system from the one you edit the source code to check it in. It will mess up the cr/lf translation!

6. Reference

Parts of this documentation are based on "Programming in C++ Rules and Recommendations", Copyright 1990-1992 by Ellemtel Telecommunication Systems Laboratories.


Original  Author:  Tak  Tsubota