Type Declaration - Pointer Asterisk Position

You are oversimplifying the structure of C++ declaration (even though the points you make are perfectly logical). Only at the first sight it might seem that C++ declaration consists of type name and a sequence of comma separated entity names, but in reality in C++ (as well as in C) declaration actually consists of type name and sequence of declarators. The full type information for an entity you declare is split between two separate locations and portion of it is actually a part of its declarator. It is just the way it is in C++. In order to better reflect the actual structure of the declaration (as seen by the language), it might be a good idea to format declarations as

int *a, *b;

i.e. explicitly group *s with the entity names, not with the type name. (But in the end it is a matter of personal preference.)

As for why it is designed that that way in the language, as you ask in one of the comments... As you know, the parts of the declaration syntax that describe the type of the entity being declared can appear on the left-hand side of the name (like * and &) as well as on its right-hand side (like () and []) as in

int *f(), (&g)[5], h[2][2];

For the bits that appear on the right it is simply impossible to do it in any other way. They have no choice but to be grouped with the entity name, not with the type name. One might ask further why the above declarations are not done in C++ as

int *() f;
int (&)[5] g;
int [2][2] h;

(i.e. everything type-related appears on the left-hand side in a compact group)... Well, the answer to this question is just that it is the way it is in C++. The approach is inherited from C and there the "declaration must resemble the use" is often quoted as the rationale.

P.S. Another thing to remember (and what is often interpreted incorrectly) is that qualifiers adjacent to the type name in the declaration are part of the common type, not a part of the first individual declarator. For example

int const *a, *b;

declares const int *a and const int *b, not int *b as some might mistakingly believe. For this reason I personally prefer to use the more logical

const int *a, *b;

ordering (even though at the same time I prefer to group * with the name, not with the type).


This is just one of the many irregularities of C's declaration syntax. The type modifier * is part of the type, yet syntactically it belongs to the identifier that's declared.
The same is true for & and [], BTW.

See here for what * does besides modifying a type.


Actually the asterisk is attached to the variable (a convention inherited from C), so

int * number1, number2;

declares number1 as a pointer to int (i.e. *number1 is an int), and number2 as an int.

The spacing has no effect on how the number's are typed. It just serves as a token separator. All of the following are the same to compiler, because the spaces will be stripped after parsing.

int *a;
int*a;
int* a;
int * a;
int/**a***/*/*a***/a;

Use

int* number1, *number2;

to create two pointers, or even better, split it into multiple declarations to avoid confusion.

int* number1;
int* number2;

Stroustrup was asked this and he said (paraphrasing)

  • if you think more C-ish you will say int *a and Employee *pE (so in your head you're thinking "the content of a is an integer")
  • if you think more C++-ish you will say int* a and Employee* pE (so in your head it's "a is an integer pointer")

You can think however you like, as long as you never declare two pointers on the same line.

Works for me. I'm an Employee* pE kind of person, but I'm married to an Employee *pE kind of person - my advice would be not to get too worked up about it.

Tags:

C++

Pointers