Work@Microsoft    Live@Seattle

The Ultimate C++ Naming Conventions for Windows Development

Rate this post

A consistent naming pattern is one of the most important elements of predictability and discoverability in C++. Widespread use and understanding of these naming guidelines should eliminate many of the most common user questions.  For these reasons and also to promote maintainability, readability, code reviews, improved learning curves, and improve general efficiency.

General Naming Conventions

Do use meaningful names for various types, functions, variables, constructs and data structures. Their use should be plainly discernable from their name alone.

Single-character variables should only be used as counters (i, j) or as coordinates (x, y, z). As a rule-of-thumb a variable should have a more descriptive name as its scope increases.

Use of Abbreviations

  • Do not use abbreviations or contractions as parts of identifier names. For example, use “GetWindow” instead of “GetWin”.
  • Do not use acronyms that are not generally accepted in the computing field.
  • Where appropriate, use well-known acronyms to replace lengthy phrase names. For example, use UI for User Interface and OLAP for On-line Analytical Processing.
  • When using acronyms, use Pascal case or camel case for acronyms more than two characters long. For example, use “”HtmlButton”” or “htmlButton”. However, you should capitalize acronyms that consist of only two characters, such as IO instead of Io.
  • Do not use abbreviations in identifiers or parameter names. If you must use abbreviations, use camel case for abbreviations that consist of more than two characters, even if this contradicts the standard abbreviation of the word.

Capitalization Styles

Use the following four conventions for capitalizing identifiers. This section can be considered a reference for capitalization styles.

  1. Pascal Case
    The first letter in the identifier and the first letter of each subsequent concatenated word are capitalized. You can use Pascal case for identifiers of three or more characters. For example:  ‘UserName’
  2. Camel Case
    The first letter of an identifier is lowercase and the first letter of each subsequent concatenated word is capitalized. For example:  ‘userName’
  3. Upper Case
    All letters in the identifier are capitalized. Use this convention only for identifiers that consist of two or fewer letters. For example:  IO, UI
  4. All Caps with Underlines
    Many developers are used to naming constants and macros with all uppercase words separated by underscore. For example: END_MACRO_TABLE;

Capitalization Rules

The following table describes the capitalization and naming rules for different types of identifiers.

IdentifierCapitalization StyleNotesExample
ClassPascalclass ComplexNumber {…};
EnumPascalenum Type { … };
Function, MethodPascalvoid PrintItem();
InterfacePascalPrefixed with an Iinterface IDictionary {…};
StructAll Caps with Underlinesstruct FORM_STREAM_HEADER
MacroAll Caps with Underlines#define BEGIN_MACRO_TABLE(name) …
ConstantAll Caps with Underlinesconst int BLACK = 3;
Local VariableCameldwCount
Template ParameterPascalPrefixed with a TTItem

Hungarian Notation

You can use Hungarian notation in parameter and variable names. However, Hungarian notation is a relic that makes code refactoring harder; i.e. change a type of a variable and you need to rename it everywhere.

The following table defines a set of suitable Hungarian notation tags should you choose to use Hungarian notation.

bool, BOOL, bitfieldfA flag. For example, BOOL fSucceeded;
BYTEAn 8 bit unsigned quantity. The use of BYTEs should be limited to opaque quantities, like cookies, bitfields, etc.
WORDAn unsigned 16 bit quantity. The use of WORDs should be limited to opaque quantities, like cookies, handles, bitfields, etc.
DWORDdwAn unsigned 32 bit quantity. The use of DWORDs should be limited to opaque quantities, like cookies, handles, bitfields, etc.
HRESULThrHRESULT values are commonly used through-out Win32 for error or status values.
HANDLEhA handle.
unsigned int
A 32 bit ordinal number (can be compared using <, <=, >, >=). NOTE: on 64 bit versions of Windows integer is 32 bits.
unsigned short
A 16-bit ordinal number. These tags should be rarely used; they are acceptable in structures for disk formats and the heap.
long, unsigned longA 32-bit ordinal number. These tags should be rarely used, as “int” accomplishes the same thing and is preferred to “long”.
__int64, LONGLONG, ULONGLONGA 64-bit ordinal number.
TCHAR, wchar_t, charchA character (sign unspecified). The “wchar_t” type is the preferred for wide characters as it’s a C++ construct. We do not have different tags for char’s and TCHARS’s because we use Unicode through the project. In the rare case of a function that contains both char’s and WCHAR’s, use “ch” for char and “wch” for wchar_t.
PWSTR, PCWSTR, wchar_t *,
PSTR, PCSTR, char *
pszA pointer to a zero-terminated string. Since we are using Unicode
wchar_t [], char []szA zero-terminated string in the form of a character array on the stack. For example, wchar_t szMessage[BUFFER_SIZE];
BSTRbstrAn OLE Automation BSTR
voidA void. Use the “p” prefix for a pointer to void.
(*)()A function. Use the “p” prefix for a pointer to function.

For example,


Hungarian Prefixes can be used to augment the type information – the prefix is used with the Hungarian tag.

pA pointer (32bit or 64 bit depending on platform).
spA ‘smart’ pointer, i.e. a class that has pointer-like semantics.
cA count. For example, cbBuffer means the byte count of a buffer. It is acceptable if “c” is not followed by a tag.
m_A member variable in a class.
s_A static member variable in a class.
g_A global variable.


For example,

UINT cch;  // Count of characters
PWSTR psz; // String pointer, null terminated
wchar_t szString[] = L"foo";

I’m a Program Manager at Microsoft (MSFT), and a part-time computer science master student in University of Washington (UW).

Leave a Comment

Your email address will not be published. Required fields are marked *