You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
511 lines
16 KiB
511 lines
16 KiB
Project Coding Conventions
|
|
|
|
***** Declarations, Naming and Hungarian
|
|
|
|
The following Hungarian conventions are used in the tree, as a minimum.
|
|
Other conventions may be added to these, but should not change the meaning of
|
|
any of these conventions. If a variable does not start with Hungarian,
|
|
it should begin with a capital letter (Foo) to so indicate. Otherwise,
|
|
the first letter after the Hungarian should be capitalized (pfnFoo).
|
|
These prefixes are ordered in the order of their precedence (So m_ is
|
|
before p is before fn, so you write m_pfnFoo).
|
|
|
|
|
|
Prefix Meaning Why
|
|
-------------------------------------------------------------------------------
|
|
g_ Global Prefix of global variables.
|
|
m_ Member of Class All methods of class will have these variables
|
|
always in scope. They need to be different to
|
|
protect the namespace in methods.
|
|
p Pointer Always helpful to know if variable is
|
|
pointer or pointer pointer (pp)
|
|
h Handle Denotes a reference to memory that cannot be
|
|
directly interpreted as a pointer
|
|
b Bool To distinguish TRUE/FALSE containing variable
|
|
from other integers
|
|
c Count (signed integer) To indicate that this integer contains a count
|
|
of something. Is signed so (--count < 0) tests
|
|
can be used.
|
|
f Floating point (single) To indicate native floating point type.
|
|
d Floating point (double)
|
|
fn Function Usually with pfn to indicate a pointer to a
|
|
function.
|
|
i Signed integer i and u are used to distinguish signed
|
|
and unsigned integers
|
|
o Offset Used to flag memory offsets. Useful in memory
|
|
structures in DSP and Chip simulations.
|
|
s String s and sz distinguish between non-zero
|
|
terminated and zero terminated strings.
|
|
sz Zero Terminated String
|
|
u Unsigned integer
|
|
|
|
|
|
'p' should be used in conjunction with a base type tag for pointers to
|
|
simple types, so a pointer to an unsigned integer is 'pu' rather than
|
|
just 'p'. Complex types do not have tags so pointers to structures or
|
|
objects will only have a 'p' prefix.
|
|
|
|
***** Differences From Other Hungarian Styles
|
|
|
|
Many kinds of Hungarian are used around the company, ranging from very
|
|
strict to very relaxed. The Hungarian described here is fairly relaxed and
|
|
the following Hungarian conventions are not used:
|
|
|
|
There is no distinction between far and near pointers. Pointers are
|
|
always 'p'; there is no 'lp'.
|
|
|
|
Arrays are not distinguished with a special prefix.
|
|
int iFoo[7] instead of int aiFoo[7] or int rgiFoo[7].
|
|
|
|
Functions are not tagged for return type.
|
|
int Foo() instead of int iFoo().
|
|
|
|
Variables holding flags are not specially distinguished.
|
|
UINT32 uFlags instead of UINT32 grfFlags or UINT32 fFlags.
|
|
|
|
Classes and structs do not have tags.
|
|
FooClass *pFoo instead of FooClass *pfcFoo.
|
|
|
|
Examples:
|
|
TCHAR g_szDllName[80];
|
|
PHANDLE phFile;
|
|
PD3DVERTEX pVtx;
|
|
|
|
C++ const's follow the Hungarian of their type. #define's are all cap's.
|
|
Classes are mixed case starting with a capital. Structures are all cap's, with
|
|
"tagNAME" used to name the structure, and "NAME" used to name the typedef:
|
|
|
|
typedef struct tagCHUNKELEM
|
|
{
|
|
struct tagCHUNKELEM *pNext;
|
|
EscNodeBase *pNode;
|
|
EscMatrix *pMatrix;
|
|
} CHUNKELEM, *PCHUNKELEM;
|
|
|
|
Structure types should always have a P<struct> typedef associated with
|
|
them and P<type> should be used in favor of <type> *.
|
|
|
|
***** Standard Types
|
|
|
|
A set of standard types of known size has been defined. These types
|
|
should be used for any data element that must be a particular size.
|
|
|
|
typedef signed char INT8;
|
|
typedef short int INT16;
|
|
typedef long int INT32;
|
|
typedef __int64 INT64;
|
|
typedef unsigned char UINT8;
|
|
typedef unsigned short int UINT16;
|
|
typedef unsigned long int UINT32;
|
|
typedef unsigned __int64 UINT64;
|
|
typedef float FLOAT;
|
|
typedef double DOUBLE;
|
|
|
|
If a data element does not require a particular size then the standard
|
|
INT and UINT types can be used. FLOAT and DOUBLE are IEEE standard formats
|
|
and take 32 and 64 bits, respectively.
|
|
|
|
The standard Win32 TCHAR should be used for strings where the character
|
|
set can be ANSI or Unicode. __TEXT() can be used to declare TCHAR
|
|
strings and the CRT file tchar.h has many standard routines #defined for
|
|
Unicode and ANSI builds.
|
|
|
|
***** Comments for Files, Functions and Code
|
|
|
|
Comments should use // instead of /* */ unless an in-line comment is
|
|
absolutely necessary.
|
|
|
|
All files must have a descriptive header comment which gives information
|
|
on the contents of the file and any other file-specific information.
|
|
|
|
C/C++ style:
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// This file contains code dealing with foo and also bar.
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1997.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
Assembly style is the same except with ; instead of //.
|
|
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
; This file has optimized routines for foo.
|
|
;
|
|
; Copyright (C) Microsoft Corporation, 1997.
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
|
|
All functions and methods must have a header comment giving an overview
|
|
of what the function does, what its inputs are and what its outputs are.
|
|
|
|
C/C++ style:
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// CreateFoo
|
|
//
|
|
// Takes a bar and a baz and creates a foo from them. If the foo is
|
|
// successfully created it is returned and the baz is updated to
|
|
// reflect the new count of foos using it.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
Assembly style has ; instead of // and more information about exactly
|
|
how the code is entered and left. If the function is declared with
|
|
arguments then no explicit documentation is necessary in the header, but
|
|
if arguments are passed in registers then the header should indicate
|
|
this. Return values are assumed to be in eax unless otherwise specified.
|
|
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
; CreateFoo
|
|
;
|
|
; Takes a bar and a baz and creates a foo from them. If the foo is
|
|
; successfully created it is returned and the baz is updated to
|
|
; reflect the new count of foos using it.
|
|
;
|
|
; Expects bar in eax and baz in ebx.
|
|
; Destroys ecx and edx.
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
|
|
All code should have at least a simple comment for each basic block and
|
|
more comments as necessary. Assembly code should be heavily commented
|
|
with notes on register and FP stack usage, unusual tricks, instruction
|
|
pairing issues, etc.
|
|
|
|
Classes should generally have a function-like comment describing the
|
|
reason for their existence and an overview of their interface. Trivial
|
|
classes do not need a comment. Structs generally need only a mention of
|
|
their use, although if they have complicated features or methods they
|
|
may need a class-like header.
|
|
|
|
***** Microsoft Internal
|
|
|
|
Any code or comments which are for internal use only are bracketed as
|
|
follows. The brackets and text are stripped for the file versions which
|
|
are made public.
|
|
|
|
//@@BEGIN_MSINTERNAL
|
|
microsoft-only stuff here
|
|
//@@END_MSINTERNAL
|
|
|
|
***** File Naming
|
|
|
|
We'll be using a mix of C and C++ so we need to distinguish files
|
|
that are C-compatible from those that are not.
|
|
|
|
Use .c for plain C files.
|
|
Use .h for plain C headers or headers which can be included safely in
|
|
plain C files. This includes headers which have C++ constructs
|
|
protected by ifdef __cplusplus. .h files that may be included in C++
|
|
code should have internal extern "C" blocks.
|
|
Use .cpp for C++ files.
|
|
Use .hpp for C++-only headers.
|
|
|
|
***** General Code Style
|
|
|
|
Lines should not exceed eighty columns. This is much more pleasant for
|
|
those of us that do not use large windows.
|
|
|
|
Functions should be fewer than one hundred lines long unless structure
|
|
or performance requires a longer function. In general functions should
|
|
be even shorter, with sub-functions created as necessary.
|
|
|
|
Any commented-out code must have an explanatory comment with it
|
|
describing why it is commented out but not removed entirely.
|
|
|
|
Global variables should be avoided unless absolutely necessary.
|
|
|
|
Use uSize members of structs that may need to be resized later with
|
|
backwards compatibility. When using uSize make sure to validate sizes
|
|
everywhere to force callers to use it properly.
|
|
|
|
Headers should be protected with #ifndef <file> #define <file> #endif
|
|
blocks for inclusion safety.
|
|
|
|
***** C++ Usage Guidelines
|
|
|
|
C++ has a lot of things in it which can make code more difficult to read
|
|
or slower. The following is a list of suggestions on things to
|
|
avoid. These rules can be broken if necessary.
|
|
|
|
Avoid overloading operators.
|
|
Avoid default parameters.
|
|
Avoid multiple inheritance.
|
|
Avoid exceptions. This means that constructors cannot fail since they
|
|
can't return anything. If an object requires initialization that can
|
|
fail the constructor should put the object in an invalid state and a
|
|
method called Initialize should be used to fully create the object.
|
|
Avoid public data members. Use accessor methods instead.
|
|
Avoid placing method bodies inline in class declarations. Bodies of
|
|
inline methods should follow the class declaration in the header file.
|
|
Avoid naming conflicts with functions so that :: is not needed.
|
|
|
|
***** C/C++ Code Style
|
|
|
|
Indentation and spacing should be done entirely with spaces; no tabs
|
|
should be used. One indentation level is four spaces.
|
|
|
|
Braces should be on separate lines and aligned with each other. All
|
|
statements must be bracketed even if they are only a single line.
|
|
|
|
Case statements should align with the brackets of the switch. break
|
|
statements in case statements should be indented once from the case.
|
|
|
|
Functions should be declared so that their name begins on the first
|
|
character of a line. Return types, calling conventions and other
|
|
decorations should be on a preceeding line. Arguments can immediately
|
|
follow the name.
|
|
|
|
Functions should always declare a return type and use (void) if they
|
|
have no arguments.
|
|
|
|
Complete Example:
|
|
|
|
foo.hpp:
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// This file contains the declaration of the Foo class.
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1997.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#ifndef _FOO_HPP_
|
|
#define _FOO_HPP_
|
|
|
|
// Flags for the Foo class.
|
|
#define FOO_INVALID 0x00000001
|
|
#define FOO_MATCH 0x00000002
|
|
|
|
// Special numbers for checking.
|
|
#define FOO_RETURN_NEGONE 0xfefefefe
|
|
#define FOO_DO_NOTHING 0xefefefef
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// class Foo
|
|
//
|
|
// The Foo class is responsible for keeping a buffer of things to check.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
class Foo
|
|
{
|
|
public:
|
|
Foo(void);
|
|
BOOL Initialize(int cElts);
|
|
~Foo(void);
|
|
|
|
int Check(int iCheck);
|
|
inline UINT32 GetFlags(void);
|
|
|
|
private:
|
|
INT m_cElts;
|
|
INT m_cUsed;
|
|
PINT m_piBuffer;
|
|
UINT32 m_uFlags;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Foo::GetFlags
|
|
//
|
|
// Accessor method for a Foo's flags.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
inline UINT32
|
|
GetFlags(void)
|
|
{
|
|
return m_uFlags;
|
|
}
|
|
|
|
#endif // _FOO_HPP_
|
|
|
|
foo.cpp:
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// This file contains the implementation of the Foo class.
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1997.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "foo.hpp"
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Foo::Foo
|
|
//
|
|
// Initializes a Foo to an invalid state.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
Foo::Foo(void)
|
|
{
|
|
m_piBuffer = NULL;
|
|
m_uFlags = FOO_INVALID;
|
|
m_cElts = 0;
|
|
m_cUsed = 0;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Foo::Initialize
|
|
//
|
|
// Constructs a Foo.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
BOOL
|
|
Foo::Initialize(int cElts)
|
|
{
|
|
// Allocate a buffer.
|
|
m_piBuffer = new int[cElts];
|
|
if (m_piBuffer == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
m_cElts = cElts;
|
|
m_uFlags = 0;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Foo::~Foo
|
|
//
|
|
// Cleans up a Foo.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
Foo::~Foo(void)
|
|
{
|
|
delete m_piBuffer;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Foo::Check
|
|
//
|
|
// Checks for the given number in the buffer. If a match is found,
|
|
// return the index of the match. If no match is found, add the number
|
|
// to the buffer and return its index. If the buffer overflows, -1 is
|
|
// returned.
|
|
//
|
|
// If the number is one of the special numbers, return its special code.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
int
|
|
Foo::Check(int iCheck)
|
|
{
|
|
int i;
|
|
|
|
// Check for initialization.
|
|
if (m_uFlags & FOO_INVALID)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
// Check for a special number.
|
|
switch(iCheck)
|
|
{
|
|
case FOO_RETURN_NEGONE:
|
|
return -1;
|
|
case FOO_DO_NOTHING:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// Look for an existing match.
|
|
for (i = 0; i < m_cUsed; i++)
|
|
{
|
|
if (m_piBuffer[i] == iCheck)
|
|
{
|
|
m_uFlags |= FOO_MATCH;
|
|
return i;
|
|
}
|
|
}
|
|
|
|
// No match was found, so add the new number if there's space.
|
|
if (m_cUsed == m_cElts)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
m_piBuffer[m_cUsed] = iCheck;
|
|
return m_cUsed++;
|
|
}
|
|
|
|
***** Assembly Style
|
|
|
|
All assembly ops and registers should be in lower case. Each line is
|
|
indented eight spaces from the left margin. Assembler directives and
|
|
macros are always in uppercase.
|
|
|
|
Complete Example:
|
|
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
; This file has optimized routines for foo.
|
|
;
|
|
; Copyright (C) Microsoft Corporation, 1997.
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
|
|
.386p
|
|
.MODEL FLAT
|
|
|
|
.CODE
|
|
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
; Foo
|
|
;
|
|
; Takes a pointer to a bar and returns the total bit count for it and its
|
|
; successor.
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
|
|
Foo PROC PUBLIC,
|
|
pBar:PBAR
|
|
|
|
LOCAL cBits:DWORD
|
|
|
|
; Get bit count for current bar.
|
|
mov ecx, pBar
|
|
mov eax, [ecx+BAR_cBits]
|
|
mov cBits, eax
|
|
|
|
; Get successor bar in ecx.
|
|
push ecx
|
|
call UpdateBar
|
|
mov ecx, eax
|
|
|
|
; Sum bit counts for return.
|
|
mov eax, cBits
|
|
add eax, [ecx+BAR_cBits]
|
|
ret
|
|
Foo ENDP
|
|
|
|
END
|
|
|
|
***** Asserts, Debug Output and Other Debugging Aids
|
|
|
|
Assert checks should be placed where appropriate. These should be used
|
|
where unexpected but still possible bad things can happen.
|
|
|
|
Note that parameter validation will occur in the D3D runtime, so checking
|
|
of state and items like vertex type is not necessary.
|
|
|
|
We will use the new DX DPF support defined in newdpf.h.
|
|
|