Beginners are often astonished to learn that the declaration
int* a, b;
declares a
as a pointer to int
and b
as an int
. This stems from the curious way in which declarations in C and C++ are divided into specifiers and declarators. A declaration begins with a single list of specifiers, but each entity declared has its own declarator, which independently modifies the specifier in order to give the resulting type of the entity. The above declaration therefore has two declarators, *a
and b
. The *
in the first declarator combines with the int
specifier to give the type int*
for a
, and the second declarator has no modifiers, so the resulting type is simply int
.
At the same time, in certain contexts a type name is expected (type-id in C++) which is the combination of specifiers and optionally an "abstract declarator", which is basically a declarator that omits the name. int*
for example is a type name. But a type name is not directly used in declarations. As we see above, int* a, b
is not interpreted as a type name followed by two identifiers, as one might expect.
So we have specifiers, declarators, and combinations of the two forming type names, but type names aren't used to declare variables of the corresponding types, even though they are literally the names of types, defined to only lack a name. What are the historical reasons for the grammar being this way, complicated and counterintuitive? Is there some benefit to being able to write code like this?
int *a, (*b)();