views:

262

answers:

5

Hello, in C++, the following means "allocate memory for an int pointer":

int* number;

So, the asterisk is part of the variable type; without it, that would mean something else (that's why I usually don't separate the asterisk from the variable type). Then what is the reason the asterisk is considered something else, instead of being part of the type? For example, it seems better, if the following meant "allocate memory for two int pointers":

int* number1, number2;

Am I wrong?

+1  A: 

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 2 pointers.

KennyTM
Thanks, but I'm not asking how I should write it. I'm questioning why the compiler is designed that way. What is the thing that makes this syntax more logical.
sahs
@sahs: There is no good reason it is the way it is except for "it's always been this way". This isn't all that logical, it's _historical_ instead. C, from which we inherited this declaration syntax is 40 years old and well predates much of what is considered good language design nowadays.
sbi
+1  A: 

No,

int* number1, number2;

Declares number1 as a pointer to int, and number2 as an int. Personally, I also prefer attaching the asterisk to the type, which suffers from exactly the gotcha you bring up in this question, so I would declare two pointers as follows:

int* number1;
int* number2;
Eli Bendersky
+4  A: 

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.

sbi
+2  A: 

Stroustrup was asked this and he said 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") but 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") and you can think however you like as long as you never declare two ponters 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.

Kate Gregory
+2  A: 

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 quited 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).

AndreyT