Declarator operators

A

anjogasa

In the midst of reading "The C++ Programming Language", the latest
edition by Stroustrup, and I find myself butting my head against a few
paragraphs. I have searched the errata on the website, and since its
not in error, my understanding must be. I quote the following:

-
From 4.9.1 - The Structure of a Declaration

A declaration consists of four parts: an optional "specifier", a base
type, a declarator, and an optional initializer.

[...]

A declarator is composed of a name and optionally some declarator
operators. The most common delcarator operators are:

* - pointer - prefix
*const - constant pointer - prefix
& - reference - prefix
[] - array - postfix
() - funtion - postfix

Their use would be simple if they were all either prefix or postfix.
However, *, [], () were designed to mirror their use in expressions.
Thus, * is prefix and [] and () are postfix. The postfix declarator
operators bind tigther than the prefix ones. Consequently, *kings[] is
an array of pointers to something, and we have to use parentheses to
express types such as "pointer to function".

-

My questions involves the sentences involving the declarator
precedence. The passage states that the postfix declarator operators,
[] and (), bind tighter than the prefix declarator operators, *,
*const, and &. The way I understand this as to how it would apply to
"*kings[]", is that the "[]" binds first, making it an array of kings,
and then the "*" binds, making it a pointer to an array of kings. The
book states though that it is "an array of pointers to something". It
would seem that "(*kings)[]" would be an array of pointers to
something, not the first example.

Anjo
 
B

Bob Hairgrove

My questions involves the sentences involving the declarator
precedence. The passage states that the postfix declarator operators,
[] and (), bind tighter than the prefix declarator operators, *,
*const, and &. The way I understand this as to how it would apply to
"*kings[]", is that the "[]" binds first, making it an array of kings,
and then the "*" binds, making it a pointer to an array of kings. The
book states though that it is "an array of pointers to something". It
would seem that "(*kings)[]" would be an array of pointers to
something, not the first example.

*kings[] by itself is not a valid expression.

class King { /*...*/ };

King kings[10]; // declares an array of 10 King objects
King *pkings[10]; // declares an array of 10 pointers to King

King k1(kings[0]); // constructs k1 with 1st element of kings[]
King k2(*pkings[0]); // constructs k2 by dereferencing
// 1st element of pkings[]

Is that somewhat clearer?
 
G

Gianni Mariani

My questions involves the sentences involving the declarator
precedence. The passage states that the postfix declarator operators,
[] and (), bind tighter than the prefix declarator operators, *,
*const, and &. The way I understand this as to how it would apply to
"*kings[]", is that the "[]" binds first, making it an array of kings,
and then the "*" binds, making it a pointer to an array of kings. The
book states though that it is "an array of pointers to something". It
would seem that "(*kings)[]" would be an array of pointers to
something, not the first example.

The trick in reading these is to read decls from the inside out (from
the "thing" being declared.

i.e. "somthing (*kings)[]" == kings -> * -> [] -> something

i.e. kings is a pointer to an array of somthing.

In this case:

"somthing *kings[]" == kings -> [] -> * -> something
 
V

Victor Bazarov

[..]
My questions involves the sentences involving the declarator
precedence. The passage states that the postfix declarator operators,
[] and (), bind tighter than the prefix declarator operators, *,
*const, and &. The way I understand this as to how it would apply to
"*kings[]", is that the "[]" binds first, making it an array of kings,

No, not an array of kings. "kings" is the identifier. Then you continue
to the right. You see []. That means that 'kings' is an _array_. Then
proceed further to the right until you can't go further. Then go left.
If the declarator is '*kings[]', then you can't go beyond the closing
bracket. 'kings' is an array of unknown dimension. But it's known that
'kings' is an array of (stepping to the left now) _pointers_. To what?
You will have to provide the type specifier now.
and then the "*" binds, making it a pointer to an array of kings.

No, not a pointer to an array. An array of pointers. And not of kings.
'kings' is the identifier.
> The
book states though that it is "an array of pointers to something". It
would seem that "(*kings)[]" would be an array of pointers to
something, not the first example.

No. The syntax "(*kings)[]" makes 'kings' a _pointer_ first (because you
cannot go right due to the closing parenthesis, and you have to go left),
and an array second. So 'kings' is (going right - stopping due to the
parenthesis - going left) a pointer to (cannot go left - due to opening
parenthesis - so going right again) an array of unknown dimension.

V
 
V

Victor Bazarov

Bob said:
My questions involves the sentences involving the declarator
precedence. The passage states that the postfix declarator operators,
[] and (), bind tighter than the prefix declarator operators, *,
*const, and &. The way I understand this as to how it would apply to
"*kings[]", is that the "[]" binds first, making it an array of kings,
and then the "*" binds, making it a pointer to an array of kings. The
book states though that it is "an array of pointers to something". It
would seem that "(*kings)[]" would be an array of pointers to
something, not the first example.


*kings[] by itself is not a valid expression.

No, but it's a valid declarator.
class King { /*...*/ };

King kings[10]; // declares an array of 10 King objects
King *pkings[10]; // declares an array of 10 pointers to King

King k1(kings[0]); // constructs k1 with 1st element of kings[]
King k2(*pkings[0]); // constructs k2 by dereferencing
// 1st element of pkings[]

Is that somewhat clearer?

That's irrelevant.

King King1, King2, *kings[] = { &King1, &King2, 0 };
// ^^^^^^^^

V
 
A

Anjo Gasa

class King { /*...*/ };
King kings[10]; // declares an array of 10 King objects
King *pkings[10]; // declares an array of 10 pointers to King

King k1(kings[0]); // constructs k1 with 1st element of kings[]
King k2(*pkings[0]); // constructs k2 by dereferencing
// 1st element of pkings[]

While I've always certainly read "King *pkings[10]" as declaring an
array of 10 pointers to King, I am confused how to square this with the
text I posted. If indeed postfix declarator operators bind tighter,
then first the postfix brackets bind:

pkings[10] // an array of 10 somethings

and then the prefix "*" binds:

*pkings[10] // a pointer to an array of 10 somethings

and then the base type:

King *pkings[10] // a pointer to an array of 10 kings

Now, I know my interpretation above is patently incorrect. However I
cannot understand how the text can be interpreted differently. Also as
far as the trick above in reading declarations, where does the basis
for this method come from?

Anjo
 
V

Victor Bazarov

Anjo said:
class King { /*...*/ };

King kings[10]; // declares an array of 10 King objects
King *pkings[10]; // declares an array of 10 pointers to King

King k1(kings[0]); // constructs k1 with 1st element of kings[]
King k2(*pkings[0]); // constructs k2 by dereferencing
// 1st element of pkings[]


While I've always certainly read "King *pkings[10]" as declaring an
array of 10 pointers to King, I am confused how to square this with the
text I posted. If indeed postfix declarator operators bind tighter,
then first the postfix brackets bind:

pkings[10] // an array of 10 somethings

and then the prefix "*" binds:

*pkings[10] // a pointer to an array of 10 somethings

But you're suddenly introducing the word "pointer" /closer/ to the name of
what's declared here. That's _tighter_. You need to follow the right
path and keep "an array of 10 somethings" _tighter_. So, it's "an array
of 10 ... pointers". 'Pointers' is _farther_ away from 'pkings' than the
'array of 10'.
and then the base type:

King *pkings[10] // a pointer to an array of 10 kings

Now, I know my interpretation above is patently incorrect. However I
cannot understand how the text can be interpreted differently.

Simply stop stumbling over your own feet. "Tighter" means "tighter". You
talk the talk, but you don't walk the walk.
> Also as
far as the trick above in reading declarations, where does the basis
for this method come from?

It's been there since 1970 when declaration syntax was first introduced to
C language. In C++ it comes from C. In C... Well, I don't know, Dennis
Ritchie and Brian Kernighan probably introduced the logic.

V
 
J

john_bode

(e-mail address removed) wrote:

[snip]
My questions involves the sentences involving the declarator
precedence. The passage states that the postfix declarator operators,
[] and (), bind tighter than the prefix declarator operators, *,
*const, and &. The way I understand this as to how it would apply to
"*kings[]", is that the "[]" binds first, making it an array of kings,

You mean, "making kings an array",
and then the "*" binds, making it a pointer to an array of kings.

You mean, "making kings an array of pointer".
The
book states though that it is "an array of pointers to something". It
would seem that "(*kings)[]" would be an array of pointers to
something, not the first example.

Anjo
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top