Declarator question

M

mdh

Sorry in advance if this is really dumb, but I am trying to get my
head around exactly what the declarator is. In the FAQ, 1.21, part of
it says "C declarations ....come in 2 parts, a base type and a
declarator......".

The example used is char *pc where the declarator " *pc" tells us
that " *pc is a character".

Can one thus broadly say that a declarator is in fact equivalent to
the base type?

So, in a more complicated expression eg char * ( *pfpc) () ; once
again "* ( *pfpc) ()" is a character?

Thanks as usual.
 
M

mdh

     In `char *pc' the base type is `char' and the declarator is
`*pc'.  The declaration -- both pieces taken together -- says that
the declarator has the base type: in this case, `*pc' has the
type `char'.  Later in the program, any place you write `*pc' you
have written an expression whose type is `char'.


thanks Eric. A little more probing.
Now if one adds a qualifyer like 'const' as in 'const char' etc,is the
type now 'const char' ?
 
J

John Bode

Sorry in advance if this is really dumb, but I am trying to get my
head around exactly what the declarator is. In the FAQ, 1.21, part of
it says "C declarations ....come in 2 parts, a base type and a
declarator......".

The example used is char *pc where the declarator " *pc" tells us
that " *pc is a character".

Can one thus broadly say that a declarator is in fact equivalent to
the base type?

So, in a more complicated expression eg char * ( *pfpc) () ; once
again "* ( *pfpc) ()" is a character?

Thanks as usual.

Pete and Eric have given you good answers, but I'd like to add a few
things.

The declarator introduces the name of the thing being declared (pc)
and any additional type information not provided by the type specifier
"char". In this case, the "pointerness" of pc is provided by the
declarator *pc.

Remember that in C, declaration mimics use. If I have a pointer to a
character, I retrieve the character value by dereferencing the pointer
like so:

c = *pc;

Thus, the expression "*pc" evaluates to a char value. So, going by
the "declaration mimics use" rule, the declaration for a pointer to
char is

char *pc;

Remember that the '*' is bound to the identifier, not the type
specifier, regardless of any whitespace. "char* pc;" is the same as
"char * pc;" and "char *pc;". If you wrote

char* pc1, pc2;

only pc1 would be declared as a pointer to char; pc2 would be a
regular char.

Array types are similar. If I want to retrieve a specific character
value from an array of char, I use the subscript operator:

c = ac;

Again, the type of the expression "ac" is char, so the declaration
for an array of char is

char ac[N];

Your function pointer also follows this rule. If I have a pointer to
a function that returns a pointer to a char, I retrieve that char
value by calling that function (using the dereferenced function
pointer), and then dereference the value returned by the function,
like so:

c = *(*pfpc)();

Hence the declaration

char *(*pfpc)();

When you come across a hairier than normal declarator, the way to read
it is to find the leftmost identifier, then work your way out,
remembering that () and [] bind before * (IOW, *a[] is an array of
pointer, not a pointer to an array). Using pfpc as an example:

pfpc -- pfpc
*pfpc -- is a pointer
(*pfpc)() -- to a function
*(*pfpc)() -- returning a pointer
char *(*pfpc)() -- to char.

Note that the type qualifier "typedef" changes things a little. In
the declaration

typedef char *(*pfpc)();

pfpc is not an instance of a pointer to a function to a pointer to
char, but is rather a synonym for the *type* "pointer to a function
returning pointer to char". You could use the typedef to make some
declarations easier to read:

typedef char *charptr; // charptr is a synonym for "char *"
typedef charptr (*fptr)(); // fptr is a synonym for charptr (*)()
fptr myptr; // myptr is a pointer to a function
// returning a pointe to char

although I tend not to do this, as typedefs sometimes obscure more
that they illuminate.
 
S

santosh

John Bode wrote:

Remember that in C, declaration mimics use. If I have a pointer to a
character, I retrieve the character value by dereferencing the pointer
like so:

c = *pc;

Thus, the expression "*pc" evaluates to a char value. So, going by
the "declaration mimics use" rule, the declaration for a pointer to
char is

char *pc;

Sometimes I wish that C had used a specific type specifier to declare
pointers like say 'ptr' as in:

ptr long lp = &some_long_object;

Then we could've done this:

some_other_long_obj = lp;

and perhaps reserved *lp to access value of lp itself.

So much more code deferences pointers than manipulating their values
that this syntax would've led to a more "cleaner" code, IMHO. But OTOH
it would've hidden the fact that an indirection is taking place. Oh
well, it three decades too late now...

<rest of excellent explanations snipped>
 
M

mdh

Pete and Eric have given you good answers, but I'd like to add a few
things.

John, I can only quote Santosh and say thank you for those "excellent
explanations".
 
D

David Thompson

I would go so far as to say that the declarator is an lvalue
of the base type.

Sort of, but not exactly, nor completely.

In general a declarator is not an expression, only similar to it.

For a pointer declarator T *p, *p is indeed a T lvalue, assuming p has
been set to a valid nonnull value i.e. a pointer to a T object.
(And for T * f(parms?) if f(args) returns such a value.)

For an array declarator T a[6], a[0] or a[5] is, but not a[6].

For a function declarator T f(int,double), f(1, 2.3) is a T _rvalue_
not an lvalue.

- formerly david.thompson1 || achar(64) || worldnet.att.net
 

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

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top