jeffb@grace.cs.washington.edu (Jeff Bowden) (05/08/89)
Here's the deal. I've got a function in C which I am translating to C++.
Here is an abstraction of what the current function does:
T *foo[ROWS][COLS];
/* ... */
void bar(/* args... */)
{
T **d = &foo[r][c];
/* Many uses of `d' all of the form ``(*d)'' */
}
Obviously, `d' is crying out ``I'm really a reference!''. Now, since c++ has
this nifty ability to specify references I would like to declare `d' as such
and change all instances of ``(*d)'' to ``d''.
Problem is, I can't figure out how to declare it. Obviously (?) it should be
either
T *&d = ...
or
T &*d = ....
But which? And how, in general, do you figure it out? I think the relevant
part of Stroustrup starts on page 269. To wit:
``Now imagine a declaration
T D1
where `T' is a type-specifier (like `int', etc.) and `D1' is a
declarator.
...
If D1 has the form
&D
or
& const D
the type of the contained identifier is `... reference to T.' ''
^^^^^^^^^^
This leads me to think that either order doesn't matter or that in all cases
the "&" has to be the first thing. The former seems unlikely so my guess is
that
T &*d = ...
is what I want. Is my interpretation correct or is there some other place in
Stroustrup which is more explicit about how references should really be
declared.
I realize that I could just test the possibilities out with a compiler but it
seems as though this really ought to be clearly documented and I'd like to
know where.
--
Say "lah vee."
hansen@pegasus.ATT.COM (Tony L. Hansen) (05/08/89)
< Summary: How do you declare a reference to a pointer to T? $ c++decl c++decl> declare x as reference to pointer to class y class y *&x That's how I do it. Tony Hansen att!pegasus!hansen, attmail!tony hansen@pegasus.att.com
pcg@aber-cs.UUCP (Piercarlo Grandi) (05/08/89)
In article <JEFFB.89May7132808@grace.cs.washington.edu> jeffb@grace.cs.washington.edu (Jeff Bowden) writes: Here's the deal. I've got a function in C which I am translating to C++. Here is an abstraction of what the current function does: T *foo[ROWS][COLS]; /* ... */ void bar(/* args... */) { T **d = &foo[r][c]; /* Many uses of `d' all of the form ``(*d)'' */ } Obviously, `d' is crying out ``I'm really a reference!''. Not so obviously. A reference is a synonym for an lvalue, i.e. a way to redefine an identifier (I hope that nobody takes seriously BS on the bottom of page 56 about `double &dr = 1;' :->). There are two cases: [1] you want `d' to always denote the `T' pointer at `foo[r][c]' [2] you want to step `d' thru `foo', starting at `foo[r][c]' In the first case then `d' is a reference of type `T *', so that `&d == &foo[r][c]'; in the second it is a pointer indeed. Now, since c++ has this nifty ability to specify references I would like to declare `d' as such and change all instances of ``(*d)'' to ``d''. So assuming that `d' is not used as a pointer, but as a synonym: auto T *(&d) = (foo[r][c]); where the paranthesis are used to emphasize the fact that `(&d)' is a reference of type `T *', just like `(foo[r][c])'; if you prefer you can also write typedef T *Tp; auto Tp &d = foo[r][c]; [Note the auto: in C++ it helps a lot (the compiler and yourself) to ALWAYS start a declaration with a storage class, especially if the declaration begins with a typedef'd type. I would like this to be made a rule, it would make compiler writing and program reading that much easier. Compare yards * length with auto yards *length or similar ambiguities. Too bad about breaking a lot of C programs, but then the rule that `struct s v;' and `s v;' are now equivalent already breaks all the C programs -- many -- in which one writes `struct screen screen' or similar verbiage...] While I agree that: I think the relevant part of Stroustrup starts on page 269. To wit: ``Now imagine a declaration T D1 where `T' is a type-specifier (like `int', etc.) and `D1' is a declarator. ... ^^^ the omitted part is essential, because it gives the rules for the `*' declaration operator, and they turn out to be identical to those of `&'. Your isolated quotation: If D1 has the form &D or & const D the type of the contained identifier is `... reference to T.' '' ^^^^^^^^^^ makes `&' appear different from `*', which (I hope) is not what is meant. Note that `D' is a declarator, and can specify (recursively) more complex syntax. Does this mean that auto int &j = i; auto int &(&k) = j; auto int &(*ip) = ???; /* (*ip) is a reference ? */ are legal indeed? Certainly extern char &(last(char [])); is legal, but then what about: extern void (&oops)(); On page 271, 3rd paragraph, BS says Not all the possibilities allowed by the above syntax are permitted. The restrictions are: [ ... about arrays and functions ... ] Should this list be extended? References may deserve extending the list of restrictions... Note the length of the discussion for a simple point: C++ is the language laywer's paradise (as if PL/1 and Ansi C were not enough... :-] :-]). -- Piercarlo "Peter" Grandi | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk Dept of CS, UCW Aberystwyth | UUCP: ...!mcvax!ukc!aber-cs!pcg Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk