Hi. I'm here to address the age-old debate of C and C++; which pointer declaration syntax to use?
All three are equivalent because arbitrary spacing is meaningless in C/C++.
The problem with C and C++ is that its built-in operators have multiple meanings. In particular *
means "pointer type", "multiplication" and "dereference". My goal when picking a convention is to, as much as possible, avoid using one that jars with another.
Therefore, we'll ignore syntax 2 because it looks so much like multiplication.
Unfortunately, there is no clear winner between the other two as each has at least one hindrance. Syntax 1 has the following:
In the code above, ptr1
is a Foo*
, but ptr2
is only a Foo
. One might have expected both to be Foo*
s. Syntax 3 avoids this by keeping the asterisk with the name:
This is really a throwback to C's desire to have you think in terms of "I am declaring a Foo
to which ptr
points".
Unfortunately, this is misleading to language newcomers because in fact you're not declaring or defining a Foo
at all. You're merely declaring a pointer; you still haven't allocated any actual Foo
for it to point to.
A newbie reading "int *a
" might think he's created an int
and now gets to use "the variable *a
" to access it, when in fact this is not the case at all; dereferencing such an undirected pointer would be very dangerous.
Further, aligning the asterisk with the variable name looks like a dereference operation. One of the biggest stumbling blocks to language newcomers is the multiple meaning of operators such as *
and &
— learning the difference between *
on the LHS as a pointer type indicator and *
on the RHS as a dereference operator is not aided if you see code that always aligns the asterisk in the same way.
Additionally, the name of the type itself is "Foo*
" (though array declaration and function type declaration syntax oddities do make this slightly more complicated in practice).
To summarise:
Rationale | #1 | #2 | #3 |
---|---|---|---|
Indicates the type properly | |||
Not surprising when declaring multiple variables | |||
Does not lie about allocation | |||
Doesn't look like dereference | |||
Doesn't look like multiplication |
In conclusion:
Foo *p
is rubbish; it has three cons and two pros. Foo* p
is great; it has one con and four pros… important pros.
Thanks for reading.
Updated 31/07/2010: Improved table layout for clarity.