Naming convention for pointer-to-foo types

K

Koster

Something I've been puzzled over for a while. This really has no consequence at
all, but I'm curious for the _reason_ behind where we commonly place the
asterisk when declaring pointer variables.

When defining a variable which is of pointer-to-foo type, it seems the
'convention' is to put the asterisk before the variable's identifier, like this:
foo *ptr;
The C standards all seem to use this conventions, but it is equally valid
(AFAIK) to place the asterisk after the variable's type, like this:
foo* ptr;
....or even on its own:
foo * ptr;
Now, am I correct in suggesting that the 'pointerness' of a variable is an
attribute of its type, rather than its identifier? After all, when specifying a
function's arguments in a declaration, we declare the argument's expected type
as pointer-to-foo:
int myFunction(foo *, foo *); /* common */
or int myFunction(foo*, foo*); /* not so common */
The qualified type of the variable is pointer-to-foo. No less than that.
As such, why do we specify the 'pointerness' of a variable by putting the
asterisk by its name, when _really_ it is an attribute of its type? To me it
seems much more logical to put the asterisk with the rest of the type, but maybe
I just think crooked.

So far I have seen only one instance of using the 'conventional' manner which is
more logical than the mentioned alternative, and that concerns pointers to
constant foos (and not mistaking them for constant pointers to foos):
foo *const ptr;
seems to be less ambiguous than
foo* const ptr;
Vice-versa however, it seems the alternative method wins:
const foo* ptr;
makes more sense to me than
const foo *ptr;

I guess though when you've been reading C for more than thirty years and you
have dreams where everyone speaks C, nothing is ambiguous. Just wanting some
opinions.

Koster
 
M

Matt Gregory

Koster said:
Something I've been puzzled over for a while. This really has no consequence at
all, but I'm curious for the _reason_ behind where we commonly place the
asterisk when declaring pointer variables.
....

I guess though when you've been reading C for more than thirty years and you
have dreams where everyone speaks C, nothing is ambiguous. Just wanting some
opinions.

My opinion is that type* foo; makes the most sense and it's the language
that doesn't make sense because type* foo, bar; doesn't mean what it looks
like it means, so I usually write type *foo; unless I'm writing C++, then
I write type* foo; because that's how everyone else seems to do it and
if you don't use commas it hides the senselessness of it all and since
there's less need to use commas in C++ declarations it makes more sense
there than it does in C. *gasp*

Matt Gregory
 
K

Kevin Bracey

In message <[email protected]>
Koster said:
When defining a variable which is of pointer-to-foo type, it seems the
'convention' is to put the asterisk before the variable's identifier, like
this:
foo *ptr;
The C standards all seem to use this conventions, but it is equally valid
(AFAIK) to place the asterisk after the variable's type, like this:
foo* ptr;
...or even on its own:
foo * ptr;
Now, am I correct in suggesting that the 'pointerness' of a variable is an
attribute of its type, rather than its identifier?
Yes.

As such, why do we specify the 'pointerness' of a variable by putting the
asterisk by its name, when _really_ it is an attribute of its type? To me
it seems much more logical to put the asterisk with the rest of the type,
but maybe I just think crooked.

The reason is that C declarations are designed to reflect the use of the
identifier. The declaration starts with a basic type, and then declares how
you would get from the identifier to that type using *, [] and ().

Thus, when you say

foo *ptr;

you are saying that "*ptr" is of type foo.

Likewise

foo func(int);

says that the expression "func(2)" is of type foo, and

foo array[10];

says that "array[n]" is of type foo. You can carry on in this vein to
construct monstrosities like

foo *(*x[10])(void);

which have to be deciphered by understanding that the expression
"*(*x[n])()" will have type foo, and working backwards from there to the
type of x (an array of 10 pointers to functions taking void and returning a
pointer to int). The example program cdecl (IIRC) in K&R will deconstruct
declarations like this.

But the really clinching argument in my view for putting the * next to the
identifier is to prevent the potential confusion arising from:

foo* fred, jim;

That makes it look as though jim will have type foo*. Writing it the
conventional way

foo *fred, jim;

can still cause potential confusion, so should be used with care, but at
least the formatting accurately reflects the meaning.
 
I

Irrwahn Grausewitz

Koster said:
Something I've been puzzled over for a while. This really has no consequence at
all, but I'm curious for the _reason_ behind where we commonly place the
asterisk when declaring pointer variables.

When defining a variable which is of pointer-to-foo type, it seems the
'convention' is to put the asterisk before the variable's identifier, like this:
foo *ptr;
The C standards all seem to use this conventions, but it is equally valid
(AFAIK) to place the asterisk after the variable's type, like this:
foo* ptr;
...or even on its own:
foo * ptr;
Yes, all three declarations are equivalent.
Now, am I correct in suggesting that the 'pointerness' of a variable is an
attribute of its type, rather than its identifier? After all, when specifying a
function's arguments in a declaration, we declare the argument's expected type
as pointer-to-foo:
int myFunction(foo *, foo *); /* common */
or int myFunction(foo*, foo*); /* not so common */
The qualified type of the variable is pointer-to-foo. No less than that.
As such, why do we specify the 'pointerness' of a variable by putting the
asterisk by its name, when _really_ it is an attribute of its type? To me it
seems much more logical to put the asterisk with the rest of the type, but maybe
I just think crooked.

It's a matter of style and readability. Consider:

foo *ptr, bar;
foo * ptr, bar;
foo* ptr, bar;

In all three cases you declare a variable of type pointer-to-foo (ptr)
and a variable of type foo (bar). Which version would you prefer to
see in actual code?

So far I have seen only one instance of using the 'conventional' manner which is
more logical than the mentioned alternative, and that concerns pointers to
constant foos (and not mistaking them for constant pointers to foos):
foo *const ptr;
seems to be less ambiguous than
foo* const ptr;
Vice-versa however, it seems the alternative method wins:
const foo* ptr;
makes more sense to me than
const foo *ptr;
Again, what if you see: const foo* ptr, bar;
I guess though when you've been reading C for more than thirty years and you
have dreams where everyone speaks C, nothing is ambiguous.
Maybe I've got a chance to really get a grip on C, then? Only fifteen
odd years to go, yippihh-yeah! ;-)

<SNIP>

Regards

Irrwahn
 
I

Irrwahn Grausewitz

Likewise

foo func(int);

says that the expression "func(2)" is of type foo, and

foo array[10];

says that "array[n]" is of type foo. You can carry on in this vein to
construct monstrosities like

foo *(*x[10])(void);
Got one for you:

char *(*(*foo[5])())();

Like it? ;o)

Irrwahn
 
M

Malcolm

Irrwahn Grausewitz said:
It's a matter of style and readability. Consider:

foo *ptr, bar;
foo * ptr, bar;
foo* ptr, bar;

In all three cases you declare a variable of type pointer-to-foo (ptr)
and a variable of type foo (bar). Which version would you prefer to
see in actual code?
Obviously number one. However why only three options?

foo *ptr; /* comment */
foo bar; /* bar holds beer pumps */

would be a better style. If the function uses so many variables that you
need to cram more than one to a line, break it up.
 
K

Kevin Easton

Koster said:
Something I've been puzzled over for a while. This really has no consequence at
all, but I'm curious for the _reason_ behind where we commonly place the
asterisk when declaring pointer variables.

When defining a variable which is of pointer-to-foo type, it seems the
'convention' is to put the asterisk before the variable's identifier, like this:
foo *ptr;
The C standards all seem to use this conventions, but it is equally valid
(AFAIK) to place the asterisk after the variable's type, like this:
foo* ptr;
...or even on its own:
foo * ptr;
Now, am I correct in suggesting that the 'pointerness' of a variable is an
attribute of its type, rather than its identifier?

In C, declarations aren't:

<type> <identifier>

instead, they are

<base type> <"expression" involving identifier>

In the case of

foo *ptr;

the base type is "foo" and the "expression involving identifier" is
"*ptr". This is supposed to be read as "*ptr has type foo".

After all, you don't write

foo[5] array;

to try and declare an array of 5 foos, do you? :)

- Kevin.
 
J

John Bode

Koster said:
Something I've been puzzled over for a while. This really has no consequence
at all, but I'm curious for the _reason_ behind where we commonly place the
asterisk when declaring pointer variables.
[snip rest]

I'm sure the C declarator syntax seemed like a good idea at the time
(declaration mimics use), but it always causes heartburn when trying
to talk about types.

The short answer as to why most people type "int *foo;" instead of
"int* foo;" or "int * foo;" is that the declarator syntax ties the
"pointerness" of a variable to the identifier, not the type specifier.
IOW, if you type

int* foo, bar;

the compiler interprets it as the *declarators* "*foo" and "bar"
having type int. It doesn't matter how much whitespace comes between
the type specifier, the asterisk, and the identifier, the asterisk is
still associated with the identifier. The type of the identifier
"foo" is pointer-to-int, but the syntax of the declaration requires
that we state it as the declarator "*foo" has type int. Therefore it
just makes more sense to write it as "int *foo;" since that reflects
how it's interpreted.

If you look up the grammar for the above declaration, it basically
breaks down like this (I'm not showing all the possible productions
for each nonterminal, just as it applies to the above declaration):

DECLARATION
DECLARATION_SPECIFIERS
TYPE_SPECIFIER
INTEGER_TYPE_SPECIFIER
SIGNED_TYPE_SPECIFIER
int
INITIALIZED_DECLARATOR_LIST
INITIALIZED_DECLARATOR_LIST
INITIALIZED_DECLARATOR
DECLARATOR
POINTER_DECLARATOR
POINTER
*
DIRECT_DECLARATOR
SIMPLE_DECLARATOR
IDENTIFIER
foo
,
INITIALIZED_DECLARATOR
DECLARATOR
DIRECT_DECLARATOR
SIMPLE_DECLARATOR
IDENTIFIER
bar
;

I think that's right. Anyway, as you can see, the pointer part of the
declaration is tied to the declarator for foo, not the type specifier.
 
B

bd

Koster said:
Something I've been puzzled over for a while. This really has no
consequence at all, but I'm curious for the _reason_ behind where we
commonly place the asterisk when declaring pointer variables. [snip]
So far I have seen only one instance of using the 'conventional' manner
which is more logical than the mentioned alternative, and that concerns
pointers to constant foos (and not mistaking them for constant pointers to
foos): foo *const ptr;
seems to be less ambiguous than
foo* const ptr;
Vice-versa however, it seems the alternative method wins:
const foo* ptr;
makes more sense to me than
const foo *ptr;

Until you have:
const foo* ptr, nonptr;

I'm not sure what foo const *x would do, but cdecl dosen't like it.
 
K

Kevin Easton

bd said:
I'm not sure what foo const *x would do, but cdecl dosen't like it.

foo const *x;

is identical in effect to:

const foo *x;

(and in fact the former is more logically consistent)

- Kevin.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,228
Members
46,818
Latest member
SapanaCarpetStudio

Latest Threads

Top