Namespaces
Variants

Identifiers

From cppreference.com
 
 
C++ language
General topics
Flow control
Conditional execution statements
if
Iteration statements (loops)
for
range-for (C++11)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications (until C++17*)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
explicit (C++11)
static

Special member functions
Templates
Miscellaneous
 
 

An identifier is an arbitrarily long sequence of digits, underscores, lowercase and uppercase Latin letters, and most Unicode characters.

Syntax

The first character of a valid identifier must be one of the following:

  • uppercase Latin letters A-Z
  • lowercase Latin letters a-z
  • underscore
  • any Unicode character with the Unicode property XID_Start

Any other character of a valid identifier must be one of the following:

  • digits 0-9
  • uppercase Latin letters A-Z
  • lowercase Latin letters a-z
  • underscore
  • any Unicode character with the Unicode property XID_Continue

The lists of characters with properties XID_Start and XID_Continue can be found in DerivedCoreProperties.txt.

Identifiers are case-sensitive (lowercase and uppercase letters are distinct), and every character is significant. Every identifier must conform to Normalization Form C.

Note: Support of Unicode identifiers is limited in most implementations, e.g. gcc (until 10).

In declarations

An identifier can be used to name objects, references, functions, enumerators, types, class members, namespaces, templates, template specializations, parameter packs(since C++11), goto labels, and other entities, with the following exceptions:

  • The identifiers that are keywords cannot be used for other purposes.
  • The only place they can be used as non-keywords is in an attribute-token (e.g. [[private]] is a valid attribute).
(since C++11)
  • The identifiers with special meaning (final, import, module(since C++20) and override) are used explicitly in a certain context rather than being regular identifiers.
    • Unless otherwise specified, any ambiguity as to whether a given identifier has a special meaning is resolved to interpret the token as a regular identifier.
(since C++11)
  • Identifiers that appear as a token or preprocessing token (i.e., not in user-defined-string-literal like operator ""id)(since C++11) of one of the following forms are reserved:
    • in the global namespace, identifiers that begin with an underscore
    • identifiers that contain a double underscore or begin with an underscore followed by an uppercase letter, except the following identifiers:
(since C++11)
  • the following macros defined in the standard library:
  • the C-style I/O library macros _IOFBF, _IOLBF and _IONBF
  • the C compatibility macros __alignas_is_defined and __alignof_is_defined (defined in <stdalign.h>)
  • the C compatibility macro __bool_true_false_are_defined (defined in <stdbool.h>)
(since C++11)
(since C++20)

“Reserved” here means that the standard library headers #define or declare such identifiers for their internal needs, the compiler may predefine non-standard identifiers of that kind, and that name mangling algorithm may assume that some of these identifiers are not in use. If the programmer uses such identifiers, the program is ill-formed, no diagnostic required.

In addition, it is undefined behavior to #define or #undef certain names in a translation unit, see reserved macro names for more details.

Zombie identifiers

As of C++14, some identifiers are removed from the C++ standard library. They are listed in the list of zombie names.

However, these identifiers are still reserved for previous standardization in a certain context. Removed member function names may not be used as a name for function-like macros, and other removed member names may not be used as a name for object-like macros in portable code.

In expressions

An identifier that names a variable, a function, specialization of a concept,(since C++20) or an enumerator can be used as an expression. The result of an expression consisting of just the identifier is the entity named by the identifier. The value category of the expression is lvalue if the identifier names a function, a variable, a template parameter object(since C++20), or a data member, and rvalue(until C++11)prvalue(since C++11) otherwise (e.g. an enumerator is an rvalue(until C++11)a prvalue(since C++11) expression, a specialization of a concept is a bool prvalue(since C++20)).

Type

The type of an identifier expression is the same as the type of the entity it names.

The following exceptions exist:

  • If the entity named by the (unqualified) identifier is a local entity, and would result in an intervening lambda expression capturing it by copy if it were named outside of an unevaluated operand in the declarative region in which the identifier appears, then the type of the expression is the type of a class member access expression naming the non-static data member that would be declared for such a capture in the closure object of the innermost such intervening lambda expression.
void f()
{
    float x, &r = x;
    
    [=]
    {
        decltype(x) y1;        // y1 has type float
        decltype((x)) y2 = y1; // y2 has type float const& because this lambda
                               // is not mutable and x is an lvalue
        decltype(r) r1 = y1;   // r1 has type float&
        decltype((r)) r2 = y2; // r2 has type float const&
    };
}
  • If the entity named is a template parameter object for a template parameter of type T, the type of the expression is const T.
(since C++20)
(since C++11)

Unqualified identifiers

Besides suitably declared identifiers, the following can be used in expressions in the same role:

(since C++11)
  • a template name followed by its argument list, such as MyTemplate<int>;
  • the character ~ followed by a class name, such as ~MyClass;
  • the character ~ followed by a decltype specifier, such as ~decltype(str).
(since C++11)