Does where I put the * symbol matter?

While watching C++ tutorials I've noticed that when using pointers or references the same people will use multiple different manners of declaring pointers/references. For instance here are a few ways I've seen pointers declared:
1
2
3
int* x;
int * y;
int *z;


Does this cause any difference in how the pointer works? If so, what?

Thanks!
There's no difference. It's just preference.


I prefer to keep it next to the type because I consider the pointer-ness to be part of the type:

 
int* x; // <- my preference 


Other people disagree.
The reason others disagree is because of cases like this;
int* x, y, z;

does that really make three int pointers?
I see. In which case, the people that are making the tutorials I'm looking at are being inconsistent with how they declare their pointers and references.

Thanks!
I prefer int *x and int &x. It just seems more straightforward.
The reason others disagree is because of cases like this;


Yes. Quite frankly, I personally consider that a language flaw.

But that's one of the many reasons I tend to not declare multiple vars on the same line.


The reason others disagree is because of cases like this;
int* x, y, z;


Does that really create 3 pointers? It would make sense if it did, considering that the data type seems to be an int pointer. Actually, a slightly more interesting question would be if the following line creates a pointer and two integers:
int *x, y, z;
int *x, y, z;

That does not create 3 pointers it creates an int pointer x and int y, z.
Last edited on
That's exactly what does happen Deathsbreed. I was asking the questions for rhetorical purposes to illustrate the ambiguity that can be caused by thinking that the pointer is part of the type rather than the individual variable.
Is ``int* p;'' right or is ``int *p;'' right?

Both are "right" in the sense that both are valid C and C++ and both have exactly the same meaning. As far as the language definitions and the compilers are concerned we could just as well say "int*p;'' or "int * p;''
The choice between "int* p;'' and "int *p;'' is not about right and wrong, but about style and emphasis.

C emphasized expressions; declarations were often considered little more than a necessary evil.
C++, on the other hand, has a heavy emphasis on types.

A "typical C programmer'' writes "int *p;'' and explains it "*p is what is the int'' emphasizing syntax, and may point to the C (and C++) declaration grammar to argue for the correctness of the style. Indeed, the * binds to the name p in the grammar.

A "typical C++ programmer'' writes "int* p;'' and explains it "p is a pointer to an int'' emphasizing type. Indeed the type of p is int*. I clearly prefer that emphasis and see it as important for using the more advanced parts of C++ well.

The critical confusion comes (only) when people try to declare several pointers with a single declaration:
int* p, p1; // probable error: p1 is not an int*

Placing the * closer to the name does not make this kind of error significantly less likely.
int *p, p1; // probable error?

Declaring one name per declaration minimizes the problem - in particular when we initialize the variables.
People are far less likely to write:
1
2
	int* p = &i;
	int p1 = p;	// error: int initialized by int* 

And if they do, the compiler will complain.

Whenever something can be done in two ways, someone will be confused. Whenever something is a matter of taste, discussions can drag on forever. Stick to one pointer per declaration and always initialize variables and the source of confusion disappears.

See The Design and Evolution of C++ for a longer discussion of the C declaration syntax.
stroustrup http://www.stroustrup.com/bs_faq2.html#whitespace
Esslercuffi wrote:
I was asking the questions for rhetorical purposes to illustrate the ambiguity that can be caused by thinking that the pointer is part of the type rather than the individual variable.


The thing is... the pointer (and the *) is part of the type everywhere else in the language. That one example is quite literally the only time I can think of that is treated differently.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
sizeof(char*);  // <- size of a pointer, not of a char

void func2(int*); // <- func2 takes a pointer as a parameter

std::vector<int*> foo;  // <- a vector of pointers

int* func();  // <- func returns a pointer -- it is not a pointer to a function

// in fact... that last one is SO important.. because the * is so clearly associated with the
//  return type.  If it was associated with the variable (func), it would indicate a
//  function pointer.  But to do that, you need to use paranthesis:

int (*funcp)(); // <- now it's a pointer to a func that returns an int
  // note the distinction here:  the parenthesis indicate the * is NOT associated with the
  // return type like it normally is... but instead is associated with the function, indicating
  // that the name 'funcp' itself is the pointer, and not the return type.

  // likewise:
int *what(); // <- putting the * next to the function name to indicate the * is associated with
  // the function doesn't work -- it's still associated with the return type.  This is not a function
  // pointer -- it's a function that returns a pointer. 


The fact that normal variables operate differently in this regard from literally everything else in the language is a huge inconsistency and IMO a flaw in the language.

So yeah... I associate * with the type -- and just keep that one "gotcha" in mind. Though really I generally don't use raw pointers very often so it rarely comes up. And when I do, I absolutely never feel the need to declare them all on one line like that.
Last edited on
I too consider int * x, y; problem a C language flaw.

Even more, i dislike inconsistency:
1
2
3
typedef int* intp;
int* x, y;
intp a, b;
type of y != type of b;
Topic archived. No new replies allowed.