I've recently decided that I just have to finally learn C/C++, and there is one thing I do not really understand about pointers or more precisely, their definition.

How about these examples:

int* test;

int *test;

int * test;

int* test,test2;

int *test,test2;

int * test,test2;

Now, to my understanding, the first three cases are all doing the same: Test is not an int, but a pointer to one.

The second set of examples is a bit more tricky. In case 4, both test and test2 will be pointers to an int, whereas in case 5, only test is a pointer, whereas test2 is a "real" int. What about case 6? Same as case 5?

@Sulthan That is true 99% of the time, but not always. Of the top of my head there was the type of templated type in templated type space requirement (pre C++11). In Foo<Bar<char>> the >> had to be written > > so as not to be treated as a right-shift.
– AnorZakenJul 29 '16 at 17:36

3

@AnorZaken You are right, that's a rather old comment. There are multiple situations when a space will change meaning, for example, the increment ++ operator cannot be split by a space, identifiers cannot be split by a space (and the result can be still legal for the compiler but with undefined runtime behavior). The exact situations are very difficult to define considering the syntax mess that C/C++ is.
– SulthanJul 29 '16 at 17:45

So Case 4 is actually a death-trap then? Is there any specification or further reading that explains why int* test,test2 only makes the first variable a pointer?
– Michael Stum♦Oct 7 '08 at 21:06

6

@ Michael Stum It's C++ so do you really think there is a logical explanation?
– Joe PhillipsOct 7 '08 at 21:07

6

Read K&R (The C Programming Language). It explains all this very clearly.
– FerruccioOct 7 '08 at 21:09

6

Cases 4, 5 and 6 are "death-traps". This is one reason why many C/C++ style gudes suggest only one declaration per statement.
– Michael BurrOct 7 '08 at 21:23

12

Whitespace is insignificant to a C compiler (ignoring the preprocessor). So no matter how many spaces there are or aren't between the asterisk and its surroundings, it has exactly the same meaning.
– ephemientOct 7 '08 at 21:59

the space before or after the asterisk is just a matter of aesthetics. However, the Google Coding standard goes with int *test (google-styleguide.googlecode.com/svn/trunk/…). Just be consistent
– user2489252Sep 15 '13 at 17:09

The "spiral" doesn't make any sense, much less the "clockwise". I'd rather name it the "right-left rule", since the syntax doesn't make you look right-bottom-left-top, only right-left.
– RuslanFeb 3 '18 at 9:38

Many coding guidelines recommend that you only declare one variable per line. This avoids any confusion of the sort you had before asking this question. Most C++ programmers I've worked with seem to stick to this.

A bit of an aside I know, but something I found useful is to read declarations backwards.

int* test; // test is a pointer to an int

This starts to work very well, especially when you start declaring const pointers and it gets tricky to know whether it's the pointer that's const, or whether its the thing the pointer is pointing at that is const.

int* const test; // test is a const pointer to an int
int const * test; // test is a pointer to a const int ... but many people write this as
const int * test; // test is a pointer to an int that's const

As others mentioned, 4, 5, and 6 are the same. Often, people use these examples to make the argument that the * belongs with the variable instead of the type. While it's an issue of style, there is some debate as to whether you should think of and write it this way:

int* x; // "x is a pointer to int"

or this way:

int *x; // "*x is an int"

FWIW I'm in the first camp, but the reason others make the argument for the second form is that it (mostly) solves this particular problem:

int* x,y; // "x is a pointer to int, y is an int"

which is potentially misleading; instead you would write either

int *x,y; // it's a little clearer what is going on here

or if you really want two pointers,

int *x, *y; // two pointers

Personally, I say keep it to one variable per line, then it doesn't matter which style you prefer.

this is bogus, what do you call int *MyFunc(void) ? a *MyFunc is a function returning an int ? no. Obviously we should write int* MyFunc(void), and say MyFunc is a function returning a int*. So to me this is clear, the C and C++ grammar parsing rules are simply wrong for variable declaration. they should have included pointer qualification as part of the shared type for the whole comma sequence.
– v.oddouMay 19 '17 at 9:07

But *MyFunc()is an int. The problem with the C syntax is mixing prefix and postfix syntax - if only postfix was used, there would be no confusion.
– Antti HaapalaDec 4 '18 at 16:52

The pointer is a modifier to the type. It's best to read them right to left in order to better understand how the asterisk modifies the type. 'int *' can be read as "pointer to int'. In multiple declarations you must specify that each variable is a pointer or it will be created as a standard variable.

1,2 and 3) Test is of type (int *). Whitespace doesn't matter.

4,5 and 6) Test is of type (int *). Test2 is of type int. Again whitespace is inconsequential.

You can think of 4, 5, and 6 as follows:
declaring the type only has to be done once, but if you want to declare a pointer to that type (by adding an asterisk) you have to do so for each variable.

When declaring a pointer variable, I always add whitespace between the variable and asterisk, even if I'm declaring more than one in a line. Not doing so makes me confuse it for a dereferencing expression nearly every time.

You can follow the same rules, but it's not a big deal if you put stars on the type side.
Remember that consistency is important, so always but the star on the same side regardless of which side you have choose.

This doesn't answer the question. Worse, if we try to infer an answer from it, then it implies the asterisk binds to the type at its left, which as everyone else has said, is false. It binds to the single variable name at its right.
– underscore_dJun 4 '17 at 20:25

Cases 1, 2 and 3 are the same, they declare pointers to int variables. Cases 3, 4 and 5 are the same, as they declare one pointer to, and one int variable respectively. If you want do declare two pointers in one line (which you shouldn't), you need to put an asterisk in front of each variable name:

int *test, *test2;

There is no certain correct way that says where the asterisk goes. int* test looks better because it is easier for us to imagine that appending * to the end of a type means "pointer to" that type. However, int *test makes more sense, because you can work with it like the minus sign in maths:

-(-x) = x

is analogous to

*(*test) = test

This has always helped me. Sadly, the upshot of it all is that sometimes I use int* test and sometimes int *test.

**test most certainly is not the same as test. *&test is the same as test. The parentheses make no difference. (And in fact since the single equals sign is assignment, not equality, the example with the minus signs doesn't work either).
– Ben VoigtFeb 11 '10 at 4:27

the last statement was not C code (no semicolon), and just to illustrate what would happen if you declare int *test, and then use the dereference operator on it. In c it should be "int *test; int i = *test;". The double minus example is also no C code (again no semicolon) but a mathematical example, and there it works perfectly to my understanding.
– wsdFeb 20 '10 at 16:12

What is the reason you should not declare two pointers in the same declaration ? No even half-decent C programmer will be confused by int *a, b; or int *a, *b;
– Michel BillaudJan 1 '16 at 20:35