for 3D positions.
The underlying datatype / datastructure should not be built into the name (avoid hungarian notation)
Routine Parameters
Routine parameters are formatted the same as local variables
Each routine parameter should have a comment indicating whether it is input (read only), output (write only) or both (read and write)
Routine Names
Routine names are in mixed uppercase and lowercase
The first letter of the first word should be in (uppercase/lowercase)???.
stand-a-lone routines involving Streaming should be prefixed with the appropriate abbreviation (SP, SM, SL, SV)
Class Member Variable
Member variables that are available to multiple routines within a class but only within the class, should be prefixed with an 'm_'.
class SP_Filter
/*-----------------------
Fields
-----------------------*/
SPreader * m_spReader;
SPwriter * m_spWriter;
U32 m_state; // State Flags
...
}
Global Variables
Global variables are always prefixed with a 'g_' otherwise they follow the local variable naming convention.
// Active Vertex Buffer
static int g_activeVertexBufferAlloc = 1024;
static TINvertex* g_activeVertexBufferNext = 0;
Constants
Named Constant variables are always prefixed with a 'c_' and then use all capitals for the entire word
const float c_PI_OVER_12 = 0.261799387799f;
Macros
Macro names are always in all capitals
// SORT VERTICES BY Y VALUES, breaking ties by x
#define SWAP(a,b,t) t=a,a=b,b=t
#define LEXGREATER(a,b) (a[1]>b[1] || (a[1] == b[1] && a[0]>b[0]))
Variable Names
Considerations in Choosing Good Variable Names
A good variable name is appropriate, readable and memorable.
- Appropriate: A variable name should fully and accurately describe the entity which it represents.
- Readable: A good variable name is easy to read and doesn't need to be deciphered by referring to other code.
- Memorable: The variable name should be easy to remember because the name is similar to the underlying concept.
Bad Name Examples
x = x - xx;
xxx = fido + SalesTax( fido );
x = x + LateFee( x1, x ) + xxx;
x = x + Interest( x1, x );
Better Name Examples
balance = balance - lastPayment;
monthlyTotal = newPurchases + SalesTax( newPurchases );
balance = balance + LateFee( cutomerID, balance ) + monthlyTotal;
balance = balance + Interest( customerID, balance );
More examples of Good vs. Bad Variable Names
Purpose of Variable | Good Names | Bad Names |
Velocity of a train | velocity, trainVelocity, velocityInMPH | velt, v, tv, x, train |
Running total of checks | runningTotal, checkTotal | written, ct, checks, CHK_TTL, x, x1 |
Lines per page | linesPerPage | lpp, lines, l, x |
Current date | currrentDate, todaysDate | cd, curr, c, x, date |
Note: Don't be afraid to use obvious words. The names currentDate and todaysDate are good names because they fully and accurately describe the idea of "current date". Programmers sometimes overlook using the ordinary words, which is often the easiest naming solution.
Problem Orientation
A good mnmonic name speaks to the problem rather than the solution. A good name tends to express the what more than the how.
EmployeeRecord * inputRecord; // Solution Space oriented (how we implement using computer programming)
vs.
EmployeeRecord * currEmployee; // Problem space oriented (we are working with employees not inputRecords)
Name Length
The optimum length for variables names is between 8 and 20 characters long. Short names tend to be too terse and not descriptive. longer names tend to take too long to type and also tend to cause layout problems which visually confuses the underlying logical structure.
Too Long:
numberOfPeopleOnTheUSAOlympicTeam
numberOfSeatsInTheStadium
maximumNumberOfPOintsInModernOlympics
Too Short:
n, np, ntm
n, ns, nsisd,
m, mp, max, points
About Right:
numTeamMembers, teamMemberCount
numSeatsInStadium, seatCount
teamPointsMax, pointsRecord
Effect of Scope
Very Short variable names are not always bad. When you give a short a variable a short name like i, it implies that the variable is a temporary value with a limited scope of operation, IE a loop, a few lines of code, one short routine, etc. When you name a variable i, you are saying it's a run-of-the-mill loop counter or array index, and doesn't have any other significance outside the few lines of code in which it is used. Global variables on the other hand should have have good descriptive names as their scope is an entire collection of routines in a file or even the whole program.
Hungarian Notation
A prefixing strategy that used to be very popular at Microsoft and other companies for embedding the data type into the variable name using short terse lowercase prefixes. This approach is no longer needed or useful, pick meaningful names instead.
// Hungarian Notation
BTYE byCountBytes; // 'by' is abbreviation for bytes
bool bDone; // 'b' is abbreviation for boolean
LPTSTR * pszStringPtr; // 'psz' is abbreviation for 'pointer to a null terminated string'
vs.
// Normal Style
BYTE countBytes;
bool done;
LPTSTR * stringPtr;
Note: Shawn because of his many years at Microsoft using Hungarian notation, will have problems breaking away from this idiom when programming.
Special Variable Types
One useful remnant from Hungarian notation is the idea of differentiating variable names that are global, constant or member fields (belong to a class interface) from normal variables. This makes it easier to quickly determine their special nature.
Solution #1: Use prefixs to differentiate (Hungarian Notation remnant)
// Prefix Global variables with 'g_'
int g_FileReadCount; // Global Variable for tracking Reads from a File
// Prefix Constant variables with 'c_'
float c_PI_OVER_12 = 0.261799387799f; // Constant representing PI / 12
// Prefix Class member variables with 'm_'
class CoolStuff {
int m_classID; // Unique ID for this instance of the class
...
};
Solution #2: Use namespaces (and access rules) to differentiate
// Declaring global variable
namespace FileIOSubsytem {
int FileReadCount;
}
// Declaring Constant variable
namespace MathConstants {
float PI_OVER_12 = 0.261799387799f; // Constant representing PI / 12
}
// Declaring Class Variables
class CoolStuff {
int classID; // Unique ID for this instance of the class
...
};
// Refering to variables
FileIOSubsystem::FileReadCount++;
float calcVal = x * MathConstants::PI_OVER_12;
return this->m_classID;
Note: In solution #2, class member fields should always be accessed via the 'this->' construct to make the member relationship explicit.
Value Qualifiers in Variable Names
Many programs have variables that represent computed values: totals, averages, maximums, etc. If you modify a name with a qualifier like Total, Sum, Average, Max, Min, Record, String, Pointer, etc put the modifier at the end of the name for all variables (post-order) or at the beginning of the name for all variables (pre-order).
// Post-Order
int revenueTotal;
int revenueAverage;
int revenueMax;
// Pre-Order
int totalRevenue;
int averageRevenue;
int maxRevenue;
Special Case: The num qualifier by convention and long usage has a special meaning to many industry programmers. Used in pre-order, it refers to a total, used in post-order it refers to an index.
int numCustomers; // Total Customers
vs.
int customerNum; // number of current customer
Tips:
- Stay consistent. pick one naming scheme and stick to it throughout your code.
- Do not use similar names in the same local scope. For Example: Don't use both revenueTotal and totalRevenue in the same routine.
- Be aware of the special conventions for the num qualifier.
Naming Loop Indices
By longstanding convention, The names i, j, and k by are customary for loop indices. Feel free to use them for short loops. However, if the loop is longer than a few lines, or is a deeply nested set of loops, you are better off giving the index a more meaningful name.
Pros (with i,j,k):
- Long standing convention, other programmers should immediately know you are using temporary loop variables
- Simple, easy to remember, and quick to type
Cons (with i,j,k):
- Cross-Talk: it's easy to forget which is which, typing i when you meant j and vice versa
- Re-use: it's all to easy to re-use i,j,k for other purposes in the parent routine, breaking the convention and making your code harder to figure out, did you mean i as loop index or i as max item.
// Acceptable
for (i = 0; i < teamCount; i++) {
for (j = 0; j < eventCount( i ); j++) {
score[i][j] = 0;
}
// More Readable and maintainable (but takes longer to type)
for (teamIndex = 0; teamIndex < teamCount; teamIndex++) {
for (eventIndex = 0; eventIndex < eventCount( eventIndex ); eventIndex++) {
score[teamIndex][eventIndex] = 0;
}
Naming Status Variables
Status variables describe the state of your program. Remember you are trying to capture what you are doing not how you are doing it.
- Avoid cryptic names, it makes it hard to read and understand
- Think of a better name than flag or state for status variables
- Avoid magic number literals (or magic number strings)
- Use meaningful names that describe what not how
- Refactor cryptic names for better names and/or wrap status variables inside meaningfully named short accessor routines instead.
// Cryptic
if ( flag ) ...
if ( statusFlag & 0x0F ) ...
if ( printFlag == 16 ) ...
if ( stateFlag == 0) ...
flag = 0x1;
statusFlag = 0x80;
printFlag = 16;
stateFlag = 0;
vs.
// Better
if ( dataReady ) ...
if ( characterType & PRINTABLE_CHAR ) ...
if ( reportType == REPORT_TYPE_ANNUAL ) ...
if ( RecalcNeeded() ) ...
dataReady = true;
characterType = CONTROL_CHAR;
reportType = REPORT_TYPE_ANNUAL;
RecalcNeededOff();
Naming Temporary Variables
Temporary variables are used to hold intermediate results of calculations, temporary place holders, and to track housekeeping values.
Be carefuly when giving variables obvious "temporary" names. Naming a variable "temp" may be a sign that you don't fully understand the problem space, you are trying to solve.
temp = sqrt( b^2 - 4*a*c );
vs.
discriminant = sqrt( b^2 - 4*a*c );
Naming Boolean Variables
Keep typical boolean names in mind (done, error, found, success)
- done, use done to indicate when an ongoing operation is done, set it to false to begin with, set it to true when completed
- error, use error to indicate an error (of some sort) has occurred, set the variable to false to begin with, set it to true if an error occurs
- found, use found to indicate whether a value has been found. Set found to false to begin with, set it to true once the value has been found.
- success or ok, use success or ok to indicate whether an operation succeeded (or failed). set the variable to false if the operation failed, set it to true if the operation succeeded.
Give Boolean variables names that imply true or false
// Unclear names
status, sourceFile, condition
// Better names
done, found, statusOK
isDone, isComplete, preambleRead, recalcNeeded,
sourceFileAvailable, sourceFileFound
Use positive boolean variable names
- Negative names like notFound, notDone, and notSuccessful are hard to read when they are negated (double negation)
Naming Enumerated Types
- Group Prefix, Make sure that it's clear that all members of the enumerated type are part of the same group by using a group prefix, COLOR_, PLANET_, MONTH_, FS_, etc.
- Type Definition, The underlying enumeration type should be treated as any other type definition
- Member Fields, The enumerated member fields should be differentiated from other variable names via a naming convention (For Instance, All capitals).
enum FilterState {
FS_WRITE_CELL = 0x0001,
FS_COPY_COUNTS = 0x0010,
FS_COPY_COMMENTS = 0x0020,
FS_COPY_BOUNDS = 0x0040,
FS_DEFAULT_STATE = (FS_WRITE_CELL | FS_COPY_COUNTS | FS_COPY_COMMENTS | FS_COPY_BOUNDS)
};
Naming Constants
Name the abstract entity the constant represents, not the specific number the constant refers to. FIVE would be a bad constant name. MAX_PASSES_NEEDED would be a good constant name.
Creating Readable Short Names
- Eliminate needless words
- Use shorter words which are synomyns to the original words
- Abbreviate (see below)
Abbreviation Guidelines
- Use standard abbreviations (common use in your field and/or are listed in a dictionary)
- Remove all nonleading vowels (computer -> cmptr, screen -> scrn, integer -> intgr, etc.)
- Remove articles: and, or, the, etc.
- Use the first letter or first few letters of each word
- Truncate consistently after the first, second, or third letter of each word
- Keep the first and last letters of each word
- Use every significant word in the name (up to 3 words)
- Remove useless suffixes (ing, ed, etc.)
- Keep the most noticeable sound in each syllable
- Be sure your abbreviation doesn't change the meaning of the variable
- Double check that your new abbreviation is not synonomous with obscene or vulgar language
- Do NOT use phonetic abbreviations (ILV2SK8)
- Iterate throught the above techniques until you get a variable name that is between 8-20 characters and still somewhat readable
More Notes on Abbreviations
- Don't abbreviate by removing one character from a word (Jun for June, or Jul for July)
- Abbreviate consistently (num or no for number but not both)
- Create names that you can prounce
- Avoid combinations that result in misreading or mispronunciation (is 'frd' equavalent 'fired', or 'Full Revenue Disbursal')
- Use a thesaurus to help resolve naming collisions among words with similar abbreviations
- Document extremely short and/or cryptic names with a glossary in the file header
/*---------------------------------------------
Variable Meaning
-------- -------
xPos x-coordinate position
NDSCMP Needs Computing
PTGTTL Point Grand Total
PTVLMX Point Value Maximum
...
---------------------------------------------*/
- Consider creating a project-level "Standard Abbreviations" document
- Names matter more to future readers of the code than to the writer.
Kinds of Names to avoid
- Avoid misleading names or abbreviations
#define FALSE 1
- Avoid names with obscene, vulgar, or unintentionally humorous connotations.
- Avoid collections of names with similar meanings (input & inputValue, recordNum and numRecords, etc.)
- Avoid variables with different meanings but similar names (clientRecs & clientReps) vs (clientRecords & clientReports)
- Avoid names that sound similar (wrap vs. rap)
- Avoid numerals in names (file1, file2, etc.)
- Avoid misspelled words in names
- Avoid words that are easily misspelled in english (reciept vs. receipt)
- Don't differentiate variable names solely by capitalization (VPN vs. vpn vs. vPN)
- Avoid using reserved keywords, standard types, variables, and routines (if necessary, use namespaces to resolve unexpected collisions)
#undefine __FILE__
int __FILE__; // Mis-use of Standard Macro name in C/C++
int then = 0; // Confusing variable name
if (__FILE__ == then) {
then = 1;
} else {
then = 2;
}
- Don't use names that have nothing to do with the problem space
// Compute 1-Ring
int shrek = 23;
float donkey = 46.0;
...
- Avoid names that contain hard-to-read characters (the letter 'l' vs. the digit '1', The letter 'O' vs. the digit '0', etc, don't use both in the same name)
-- ShawnDB - 19 Jun 2008
to top