9 Declarations [dcl.dcl]

9.1 Preamble [dcl.pre]

Declarations generally specify how names are to be interpreted.
declaration:
	block-declaration
	nodeclspec-function-declaration
	function-definition
	template-declaration
	deduction-guide
	explicit-instantiation
	explicit-specialization
	export-declaration
	linkage-specification
	namespace-definition
	empty-declaration
	attribute-declaration
block-declaration:
	simple-declaration
	asm-declaration
	namespace-alias-definition
	using-declaration
	using-enum-declaration
	using-directive
	static_assert-declaration
	alias-declaration
	opaque-enum-declaration
nodeclspec-function-declaration:
	attribute-specifier-seq declarator ;
alias-declaration:
	using identifier attribute-specifier-seq = defining-type-id ;
simple-declaration:
	decl-specifier-seq init-declarator-list ;
	attribute-specifier-seq decl-specifier-seq init-declarator-list ;
	attribute-specifier-seq decl-specifier-seq ref-qualifier [ identifier-list ] initializer ;
static_assert-declaration:
	static_­assert ( constant-expression ) ;
	static_­assert ( constant-expression , string-literal ) ;
empty-declaration:
	;
attribute-declaration:
	attribute-specifier-seq ;
Note
: — end note
 ]
Attributes are described in [dcl.attr].
decl-specifiers, the principal components of a decl-specifier-seq, are described in [dcl.spec].
declarators, the components of an init-declarator-list, are described in [dcl.decl].
The attribute-specifier-seq appertains to each of the entities declared by the declarators of the init-declarator-list.
Note
:
In the declaration for an entity, attributes appertaining to that entity may appear at the start of the declaration and after the declarator-id for that declaration.
— end note
 ]
Example
:
[[noreturn]] void f [[noreturn]] ();    // OK
— end example
 ]
Except where otherwise specified, the meaning of an attribute-declaration is implementation-defined.
A declaration occurs in a scope; the scope rules are summarized in [basic.lookup].
A declaration that declares a function or defines a class, namespace, template, or function also has one or more scopes nested within it.
These nested scopes, in turn, can have declarations nested within them.
Unless otherwise stated, utterances in [dcl.dcl] about components in, of, or contained by a declaration or subcomponent thereof refer only to those components of the declaration that are not nested within scopes nested within the declaration.
In a simple-declaration, the optional init-declarator-list can be omitted only when declaring a class or enumeration, that is, when the decl-specifier-seq contains either a class-specifier, an elaborated-type-specifier with a class-key ([class.name]), or an enum-specifier.
In these cases and whenever a class-specifier or enum-specifier is present in the decl-specifier-seq, the identifiers in these specifiers are among the names being declared by the declaration (as class-names, enum-names, or enumerators, depending on the syntax).
In such cases, the decl-specifier-seq shall introduce one or more names into the program, or shall redeclare a name introduced by a previous declaration.
Example
:
enum { };           // ill-formed
typedef class { };  // ill-formed
— end example
 ]
If the value of the expression when so converted is true, the declaration has no effect.
Otherwise, the program is ill-formed, and the resulting diagnostic message ([intro.compliance]) shall include the text of the string-literal, if one is supplied, except that characters not in the basic source character set are not required to appear in the diagnostic message.
Example
:
static_assert(sizeof(int) == sizeof(void*), "wrong pointer size");
— end example
 ]
An empty-declaration has no effect.
If the decl-specifier-seq contains any decl-specifier other than static, thread_­local, auto ([dcl.spec.auto]), or cv-qualifiers, the program is ill-formed.
The initializer shall be of the form “= assignment-expression”, of the form “{ assignment-expression }”, or of the form “( assignment-expression )”, where the assignment-expression is of array or non-union class type.
Each init-declarator in the init-declarator-list contains exactly one declarator-id, which is the name declared by that init-declarator and hence one of the names declared by the declaration.
The defining-type-specifiers in the decl-specifier-seq and the recursive declarator structure of the init-declarator describe a type ([dcl.meaning]), which is then associated with the name being declared by the init-declarator.
If the decl-specifier-seq contains the typedef specifier, the declaration is called a typedef declaration and the name of each init-declarator is declared to be a typedef-name, synonymous with its associated type ([dcl.typedef]).
If the decl-specifier-seq contains no typedef specifier, the declaration is called a function declaration if the type associated with the name is a function type ([dcl.fct]) and an object declaration otherwise.
Syntactic components beyond those found in the general form of declaration are added to a function declaration to make a function-definition.
An object declaration, however, is also a definition unless it contains the extern specifier and has no initializer ([basic.def]).
An object definition causes storage of appropriate size and alignment to be reserved and any appropriate initialization ([dcl.init]) to be done.
A nodeclspec-function-declaration shall declare a constructor, destructor, or conversion function.