Is there a "good" way to write "pointer to something" in C/C++ ?
I use to write void foo( char *str );
But sometimes I find it quite illogical because the type of str
is "pointer to char", then it should more logical to attach the *
to the type name.
Is there a rule to write pointers ?
char*str;
char* str;
char *str;
char * str;
The common C convention is to write
T *p
, whereas the common C++ convention is to writeT* p
. Both parse asT (*p)
; the*
is part of the declarator, not the type specifier. It's purely an accident of pointer declaration syntax that you can write it either way.C (and by extension, C++) declaration syntax is expression-centric; IOW, the form of a declaration should match the form of an expression of the same type in the code.
For example, suppose we had a pointer to
int
, and we wanted to access that integer value. To do so, we dereference the pointer with the*
indirection operator, like so:The type of the expression
*p
isint
; thus, it follows that the declaration ofp
should beThe int-ness of
p
is provided by the type specifierint
, but the pointer-ness ofp
is provided by the declarator*p
.As a slightly more complicated example, suppose we had a pointer to an array of
float
, and wanted to access the floating point value at thei
'th element of the array through the pointer. We dereference the array pointer and subscript the result:The type of the expression
(*ap)[i]
isfloat
, so it follows that the declaration of the array pointer isThe float-ness of
ap
is provided by the type specifierfloat
, but the pointer-ness and array-ness are provided by the declarator(*ap)[N]
. Note that in this case the*
must explicitly be bound to the identifer;[]
has a higher precedence than unary*
in both expression and declaration syntax, sofloat* ap[N]
would be parsed asfloat *(ap[N])
, or "array of pointers tofloat
", rather than "pointer to array offloat
". I suppose you could write that asbut I'm not sure what the point would be; it doesn't make the type of
ap
any clearer.Even better, how about a pointer to a function that returns a pointer to an array of pointer to
int
:Again, at least two of the
*
operators must explicitly be bound in the declarator; binding the last*
to the type specifier, as injust indicates confused thinking IMO.
Even though I use it in my own C++ code, and even though I understand why it became popular, the problem I have with the reasoning behind the
T* p
convention is that it just doesn't apply outside of the simplest of pointer declarations, and it reinforces a simplistic-to-the-point-of-being-wrong view of C and C++ declaration syntax. Yes, the type ofp
is "pointer to T", but that doesn't change the fact that as far as the language grammar is concerned*
binds to the declarator, not the type specifier.For another case, if the type of
a
is "N-element array of T", we don't writeObviously, the grammar doesn't allow it. Again, the argument just doesn't apply in this case.
EDIT
As Steve points out in the comments, you can use typedefs to hide some of the complexity. For example, you could rewrite
as something like
Now you can cleanly apply the
T* p
convention, declaringf
asarrptrfunc* f
. I personally am not fond of doing things this way, since it's not necessarily clear from the typedef howf
is supposed to be used in an expression, or how to use an object of typearrptrfunc
. The non-typedef'd version may be ugly and difficult to read, but at least it tells you everything you need to know up front; you don't have to go digging through all the typedefs.