4.7 KiB
[dcl.spec.general]
9 Declarations [dcl]
9.2 Specifiers [dcl.spec]
9.2.1 General [dcl.spec.general]
The specifiers that can be used in a declaration are
decl-specifier:
storage-class-specifier
defining-type-specifier
function-specifier
friend
typedef
constexpr
consteval
constinit
inline
decl-specifier-seq:
decl-specifier attribute-specifier-seqopt
decl-specifier decl-specifier-seq
The optional attribute-specifier-seq in a decl-specifier-seq appertains to the type determined by the precedingdecl-specifiers ([dcl.meaning]).
The attribute-specifier-seq affects the type only for the declaration it appears in, not other declarations involving the same type.
At most one of each of the decl-specifiersfriend, typedef, or inline shall appear in a decl-specifier-seq.
At most one of the constexpr, consteval, and constinit keywords shall appear in a decl-specifier-seq.
If a type-name is encountered while parsing a decl-specifier-seq, it is interpreted as part of the decl-specifier-seq if and only if there is no previous defining-type-specifier other than a cv-qualifier in thedecl-specifier-seq.
The sequence shall be self-consistent as described below.
[Example 1: typedef char* Pc;static Pc; // error: name missing
Here, the declaration static Pc is ill-formed because no name was specified for the static variable of type Pc.
To get a variable called Pc, a type-specifier (other thanconst or volatile) has to be present to indicate that the typedef-name Pc is the name being (re)declared, rather than being part of the decl-specifier sequence.
For another example,void f(const Pc); // void f(char* const) (not const char*)void g(const int Pc); // void g(const int)
â end example]
[Note 1:
Since signed, unsigned, long, and short by default imply int, a type-name appearing after one of those specifiers is treated as the name being (re)declared.
[Example 2: void h(unsigned Pc); // void h(unsigned int)void k(unsigned int Pc); // void k(unsigned int) â end example]
â end note]