It's being defined right there and then. It's a way of carrying whatever comes before T
across to the next type, similar to:
<some stuff> T
<some stuff> reference to T
It's just whatever comes before T
in the type of T D1
.
For example, if you have the declaration int& (*const * p)[30]
, T
is int
, D
is & (*const * p)[30]
and D1
is (*const * p)[30]
. The type of T D1
is "pointer to const pointer to array of 30 int". And so, according to the rule you quoted, the type of p
is "pointer to const pointer to array of 30 reference to int".
Of course, this declaration is then disallowed by §3.4.2/5:
There shall be no references to references, no arrays of references, and no pointers to references.
I think the informal terminology of it being a derived declarator type list comes from the C standard's definition of a derived type (similar to a compound type in C++):
Any number of derived types can be constructed from the object, function, and
incomplete types, as follows:
- An array type [...]
- An structure type [...]
- An union type [...]
- An function type [...]
- An pointer type [...]
In response to the comments: It seems you're getting confused between the type and the declarator. For example, if int* p
is the declarator, then the type of p
is "pointer to int". The type is expressed as these English-like sentences.
Example 1: int *(&p)[30]
This is a declaration T D
where (§8.3.1 Pointers):
D
has the form:
*
attribute-specifier-seqopt cv-qualifier-seqopt D1
where D1
is (&p)[3]
. That means T D1
is of the form int (&p)[3]
which has type "reference to array of 3 int
" (you work this out recursively, next step using §8.3.4 Arrays and so on). Everything before the int
is the derived-declarator-type-list. So we can infer that p
in our original declaration has type "reference to array of 3 pointer to int
". Magic!
Example 2: float (*(*(&e)[10])())[5]
This is a declaration T D
where (§8.3.4 Arrays):
T
-> float
D
-> (*(*(&e)[10])())[5]
D
is of the form:
D1 [
constant-expressionopt ]
attribute-specifier-seqopt
where D1
is (*(*(&e)[10])())
. This means T D1
is of the form float (*(*(&e)[10])())
which has type "reference to array of 10 pointer to function of () returning pointer to float" (which you work out by applying §8.3/6 and then §8.3.1 Pointers and so on). Everything before the float
is the derived-declarator-type-list. So we can infer that p
in our original declaration has type "reference to array of 10 pointer to function of () returning pointer to array of 5 float". Magic again!