Declarations are how names are introduced (or re-introduced) into the C++ program. Not all declarations actually declare anything, and each kind of entity is declared differently. Definitions are declarations that are sufficient to use the entity identified by the name.
A declaration is one of the following:
;
);
);
attr - (since C++11) sequence of any number of attributes declarator - a function declarator
A simple declaration is a statement that introduces, creates, and optionally initializes one or several identifiers, typically variables.
decl-specifier-seq init-declarator-list (optional);
(1) attr decl-specifier-seq init-declarator-list ;
(2) (since C++11) decl-specifier-seq - sequence of specifiers init-declarator-list - comma-separated list of init-declarator s (see below) attr - sequence of any number of attributes
init-declarator-list can only be omitted when declaring a named class or a named enumeration.
The syntax of init-declarator is defined as follows:
1) A declarator with an initializer.
2) A declarator without an initializer.
requires-clause can only appear if declarator declares a templated function.
(since C++20)contract-specs can only appear if declarator declares a function or function template.
(since C++26) [edit] SpecifiersDeclaration specifiers (decl-specifier-seq) is a sequence of the following whitespace-separated specifiers, in any order:
typedef
specifier. If present, the entire declaration is a typedef declaration and each declarator introduces a new type name, not an object or a function.inline
, virtual
, explicit
), only allowed in function declarations.inline
specifier is also allowed on variable declarations.friend
specifier, allowed in class and function declarations.constexpr
specifier, only allowed in variable definitions, function and function template declarations, and the declaration of static data members of literal type.consteval
specifier, only allowed in function and function template declarations.constinit
specifier, only allowed in declaration of a variable with static or thread storage duration. At most one of the constexpr, consteval, and constinit specifiers is allowed to appear in a decl-specifier-seq.Attributes may appear in decl-specifier-seq, in which case they apply to the type determined by the preceding specifiers.
Repetitions of any specifier in a decl-specifier-seq, such as const static const, or virtual inline virtual are errors, except that long is allowed to appear twice(since C++11).
[edit] DeclaratorsEach init-declarator in an init-declarator-list S D1, D2, D3; is processed as if it were a standalone declaration with the same specifiers: S D1; S D2; S D3;.
Each declarator introduces exactly one object, reference, function, or (for typedef declarations) type alias, whose type is provided by decl-specifier-seq and optionally modified by operators such as & (reference to) or [] (array of) or () (function returning) in the declarator. These operators can be applied recursively, as shown below.
A declarator is one of the following:
unqualified-id attr (optional) (1) qualified-id attr (optional) (2)...
identifier attr (optional) (3) (since C++11) *
attr (optional) cv (optional) declarator (4) nested-name-specifier *
attr (optional) cv (optional) declarator (5) &
attr (optional) declarator (6) &&
attr (optional) declarator (7) (since C++11) noptr-declarator [
constant-expression (optional) ]
attr (optional) (8) noptr-declarator (
parameter-list )
cv (optional) ref (optional) except (optional) attr (optional) (9) (
declarator )
(10) 1)
The
namethat is declared.
4) Pointer declarator: the declaration
S * D;declares
D
as a pointer to the type determined by
decl-specifier-seqS
.
6) Lvalue reference declarator: the declaration
S & D;declares
D
as an lvalue reference to the type determined by
decl-specifier-seqS
.
7) Rvalue reference declarator: the declaration
S && D;declares
D
as an rvalue reference to the type determined by
decl-specifier-seqS
.
8) Array declarator.
noptr-declaratorany valid declarator, but if it begins with *, &, or &&, it has to be surrounded by parentheses.
9) Function declarator.
noptr-declaratorany valid declarator, but if it begins with *, &, or &&, it has to be surrounded by parentheses.
It may end with the optional trailing return type.(since C++11)10) Parenthesized declarator.
In all cases, attr is an optional sequence of attributes. When appearing immediately after the identifier, it applies to the object being declared.
(since C++11)cv is a sequence of const and volatile qualifiers, where either qualifier may appear at most once in the sequence.
[edit] NotesWhen a block-declaration appears inside a block, and an identifier introduced by a declaration was previously declared in an outer block, the outer declaration is hidden for the remainder of the block.
If a declaration introduces a variable with automatic storage duration, it is initialized when its declaration statement is executed. All automatic variables declared in a block are destroyed on exit from the block (regardless how the block is exited: via exception, goto, or by reaching its end), in order opposite to their order of initialization.
[edit] ExampleNote: this example demonstrates how some complex declarations are parsed in terms of the language grammar. Other popular mnemonics are: the spiral rule, reading inside-out, and declaration mirrors use. There is also an automated parser at https://cdecl.org.
#include <type_traits> struct S { int member; // decl-specifier-seq is "int" // declarator is "member" } obj, *pObj(&obj); // decl-specifier-seq is "struct S { int member; }" // declarator "obj" declares an object of type S // declarator "*pObj" declares a pointer to S, // and initializer "(&obj)" initializes it int i = 1, *p = nullptr, f(), (*pf)(double); // decl-specifier-seq is "int" // declarator "i" declares a variable of type int, // and initializer "= 1" initializes it // declarator "*p" declares a variable of type int*, // and initializer "= nullptr" initializes it // declarator "f()" declares (but doesn't define) // a function taking no arguments and returning int // declarator "(*pf)(double)" declares a pointer to function // taking double and returning int int (*(*var1)(double))[3] = nullptr; // decl-specifier-seq is "int" // declarator is "(*(*var1)(double))[3]" // initializer is "= nullptr" // 1. declarator "(*(*var1)(double))[3]" is an array declarator: // Type declared is: "(*(*var1)(double))" array of 3 elements // 2. declarator "(*(*var1)(double))" is a pointer declarator: // Type declared is: "(*var1)(double)" pointer to array of 3 elements // 3. declarator "(*var1)(double)" is a function declarator: // Type declared is: "(*var1)" function taking "(double)", // returning pointer to array of 3 elements. // 4. declarator "(*var1)" is a pointer declarator: // Type declared is: "var1" pointer to function taking "(double)", // returning pointer to array of 3 elements. // 5. declarator "var1" is an identifier. // This declaration declares the object var1 of type "pointer to function // taking double and returning pointer to array of 3 elements of type int" // The initializer "= nullptr" provides the initial value of this pointer. // C++11 alternative syntax: auto (*var2)(double) -> int (*)[3] = nullptr; // decl-specifier-seq is "auto" // declarator is "(*var2)(double) -> int (*)[3]" // initializer is "= nullptr" // 1. declarator "(*var2)(double) -> int (*)[3]" is a function declarator: // Type declared is: "(*var2)" function taking "(double)", returning "int (*)[3]" // ... int main() { static_assert(std::is_same_v<decltype(var1), decltype(var2)>); }[edit] Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR Applied to Behavior as published Correct behavior CWG 482 C++98 the declarators of redeclarations could not be qualified qualified declarators allowed CWG 569 C++98 a single standalone semicolon was not a valid declaration it is an empty declaration,RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4