General topics | ||||||||||||||||
Flow control | ||||||||||||||||
Conditional execution statements | ||||||||||||||||
Iteration statements (loops) | ||||||||||||||||
Jump statements | ||||||||||||||||
Functions | ||||||||||||||||
Function declaration | ||||||||||||||||
Lambda function expression | ||||||||||||||||
inline specifier | ||||||||||||||||
Dynamic exception specifications(until C++17*) | ||||||||||||||||
noexcept specifier(C++11) | ||||||||||||||||
Exceptions | ||||||||||||||||
Namespaces | ||||||||||||||||
Types | ||||||||||||||||
Specifiers | ||||||||||||||||
| ||||||||||||||||
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 | ||||||||||||||||
| ||||||||||||||||
Special member functions | ||||||||||||||||
Templates | ||||||||||||||||
Miscellaneous | ||||||||||||||||
Anidentifier is an arbitrarily long sequence of digits, underscores, lowercase and uppercase Latin letters, and most Unicode characters.
The first character of a valid identifier must be one of the following:
Any other character of a valid identifier must be one of the following:
The lists of characters with properties XID_Start and XID_Continue can be found inDerivedCoreProperties.txt.
Identifiers are case-sensitive (lowercase and uppercase letters are distinct), and every character is significant. Every identifier must conform toNormalization Form C.
Note: Support of Unicode identifiers is limited in most implementations, e.g.gcc (until 10).
Contents |
An identifier can be usedto 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:
| (since C++11) |
| (since C++11) |
(since C++11) |
| (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, seereserved macro names for more details.
As of C++14, some identifiers are removed from the C++ standard library. They are listed in thelist 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.
An identifier that names a variable, a function,specialization of aconcept,(since C++20) or an enumerator can be used as anexpression. The result of an expression consisting of just the identifier is the entity named by the identifier. Thevalue category of the expression islvalue if the identifier names a function, a variable, atemplate parameter object(since C++20), or a data member, andrvalue(until C++11)prvalue(since C++11) otherwise (e.g. anenumerator isan rvalue(until C++11)a prvalue(since C++11) expression, a specialization of a concept is a bool prvalue(since C++20)).
The type of an identifier expression is the same as the type of the entity it names.
The following exceptions exist:
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&};}
| (since C++11) |
Besides suitably declared identifiers, the following can be used in expressions in the same role:
| (since C++11) |
| (since C++11) |
| (since C++26) |
Together with identifiers they are known asunqualified identifier expressions.
Aqualified identifier expression is an unqualified identifier expression prepended by a scope resolution operator::, and optionally, a sequence of any of the following separated by scope resolution operators:
| (since C++11) |
| (since C++26) |
For example, the expressionstd::string::npos is an expression that names the static membernpos in the classstring in namespacestd. The expression::tolower names the functiontolower in the global namespace. The expression::std::cout names the global variablecout in namespacestd, which is a top-level namespace. The expressionboost::signals2::connection names the typeconnection declared in namespacesignals2, which is declared in namespaceboost.
The keywordtemplate may appear in qualified identifiers as necessary to disambiguatedependent template names.
Seequalified lookup for the details of the name lookup for qualified identifiers.
If an identifier expressionE denotes a non-static non-type member of some classC
and all following conditions are satisfied,E is transformed into the class member access expressionthis->E:
C
is the innermost enclosing class atE.C
is a base class of the innermost enclosing class atE.This transformation does not apply in the template definition context (seedependent names).
struct X{int x;}; struct B{int b;}; struct D: B{ X d; void func(){ d;// OK, will be transformed into this->d b;// OK, will be transformed into this->b x;// Error: this->x is ill-formed d.x;// OK, will be transformed into this->d.x// instead of d.this->x or this->d.this->x}};
Aname is the use of one of the following to refer to an entity:
| (since C++11) |
Every name is introduced into the program by adeclaration. A name used in more than one translation unit may refer to the same or different entities, depending onlinkage.
When the compiler encounters an unknown name in a program, it associates it with the declaration that introduced the name by means ofname lookup, except for thedependent names in template declarations and definitions (for those names, the compiler determines whether they name a type, a template, or some other entity, which may requireexplicit disambiguation).
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
CWG 1440 | C++11 | decltype expressions preceding:: could denote any type | can only denote class or enumeration types |
CWG 1963 | C++11 | implementation-defined characters other than digits, non-digits and universal character names could be used in an identifier | prohibited |
CWG 2521 | C++11 | the identifier inuser-defined-string-literal of a literal operator was reserved as usual | the rules are different |
CWG 2771 | C++98 | &a was not transformed into&this->a in class contexts | it is transformed |
CWG 2777 | C++20 | the type of an identifier expression was unclear if it names a template parameter object | made clear |
CWG 2818 | C++98 | predefined macro names are reserved | they are not reserved |
C documentation forIdentifiers |