home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.std.c++
- Path: sparky!uunet!microsoft!hexnut!jimad
- From: jimad@microsoft.com (Jim Adcock)
- Subject: Re: Alternatives to operator.()
- Message-ID: <1992Jul23.024159.18039@microsoft.com>
- Date: 23 Jul 92 02:41:59 GMT
- Organization: Microsoft Corporation
- References: <BrM3LI.CBo@world.std.com> <1992Jul20.235728.29058@microsoft.com> <Brqq7D.97w@world.std.com>
- Lines: 215
-
- In article <Brqq7D.97w@world.std.com> wmm@world.std.com (William M Miller) writes:
- |Yes, I've read your "answers" (see, I can use the quote key, too --
- |can we agree to stop casting aspersions on the validity of one
- |another's mental processes and just deal with the issues
- |dispassionately?).
-
- This would require some understanding and memory retention of my prior
- statements on your part so that I do not have to keep repeatedly answering
- your same mistakes made over and over again.
-
- |The reason I listed my objections here was to
- |demonstrate that none of them were comparative, not to elicit further
- |discussion of them.
-
- Yet when your objections are stated in error, then I have to further
- discuss them. Whereas if you read and understood my corrections to
- your erroneous objections, and retracted those erroneous objections,
- then we could go on to something more constructive.
-
- |is. So is "::". I contend that "." is more like "::" than like "->".
-
- I have addressed this argument previously. Built-in operator-> means
- the same as "(*ptr)." thus if the "." performs no action then *ptr and
- ptr-> should have the same action. BUT, the language already allows
- operator*() and operator->() to be overloaded independently, resulting
- in DIFFERENT actions. So, the EXISTING C++ LANGUAGE DEFINITION contradicts
- your position. To make your position defendable, overloadable operator->()
- would have to be removed from the language, leaving operator->() to ALWAYS
- have the built-in equivalence "(*ptr)." In which case the actions of -> and .
- would always be consistent. BUT, given that operator->() CAN be overloaded,
- the operator.() MUST be overloadable too, so that the relationship
- "ptr->" <==> "(*ptr)." can be maintained by the programmer.
-
- ------
-
- Your mis-statements below simply reflect a fundamental misunderstanding
- of the language and how it works:
-
- | struct X { int i; };
- |
- | int i;
- |
- | void f() {
- | int i;
- | X x;
- | X* xp;
- | X& xr = x;
- |
- | // reference expression
- |
- | }
- |
- |Consider each of the following expressions at the location indicated
- |by the comment "reference expression":
- |
- | Expression Interpretation
- | ---------- --------------
- |
- | i Fetch the value at the appropriate offset in
- | f()'s stack frame
-
- Plain Wrong. The expression "i" at this location means "reference to the object
- named by i". Your interpretation is simply in error, as can be seen
- by using your expression "i" as follows:
-
- i = 5;
-
- If "i" means "Fetch the value...." then one value is being assigned to
- another value, which simply does not make sense. Under your interpretation
- then, "i = 5" would have to be a compiler error.
-
- | ::i Fetch the value at the appropriate offset in
- | the program's static storage region
-
- Plain Wrong. The expression "::i" at this location means "reference to the
- object named by ::i". Your interpretation is simply in error, as can be seen
- by using your expression "::i" as follows:
-
- ::i = 5;
-
- If "::i" means "Fetch the value...." then one value is being assigned to
- another value, which simply does not make sense. Under your interpretation
- then, "::i = 5" would have to be a compiler error.
-
- | x.i Fetch the value at the appropriate offset in
- | the object "x"
-
- Plain Wrong. The expression "x.i" at this location means "reference to the
- object named by 'x.i'". Your interpretation is simply in error, as can be seen
- by using your expression "x.i" as follows:
-
- x.i = 5;
-
- If "x.i" means "Fetch the value...." then one value is being assigned to
- another value, which simply does not make sense. Under your interpretation
- then, "x.i = 5" would have to be a compiler error.
-
- LIKEWISE the expression "x" must itself be a reference. "." applied
- to this reference "dereferences" it to get to the specified referenced
- member.
-
- | (*xp).i Fetch the value at the appropriate offset in
- | the object found by indirecting through the
- | value of "xp"
-
- Wrong, same reasons.
-
- | xp->i Fetch the value at the appropriate offset in
- | the object found by indirecting through the
- | value of "xp"
-
- Wrong, same reasons.
-
- | xr.i Fetch the value at the appropriate offset in
- | the object to which "xr" refers, i.e., "x"
-
- Wrong, same reasons.
-
- |Notice that each of these interpretations begins with the same phrase,
- |regardless of the presence or absence of "." in the expression.
-
- Agreed, its just that in every case you use the wrong phrase, and
- thereby in every case come to the wrong conclusions. Whereas if you
- understood the language correctly, you would come to the right conclusions.
-
- |The only difference is the context in which the offset is applied. In two
- |of the cases, (*xp).i and xp->i, there is an explicit indirection,
- |which is the overloadable operation. In the case of "xr.i" there is
- |deliberate ambiguity as to whether an indirection occurs; a reference
- |may be, but need not be, implemented by a pointer.
-
- On the contrary, if your phrases above were correct, you would find
- that in all cases an indirection occurs. Its just that in some built-in
- cases the compiler is smart enough to commonly optimize out the indirection.
-
- |The point of this exercise was to demonstrate that, semantically, the
- |builtin "." only provides qualification for the right hand side --
- |i.e., an addressing context and a scope in which the right hand side
- |can be looked up to determine "the appropriate offset" for the
- |interpretation. This is exactly what "::" -- or even the absence of
- |qualification -- does. I don't imagine this analysis will convince
- |you.
-
- It can't convince me because quite simply it is in error, as noted above.
-
- |but perhaps you can at least acknowledge that this interpretation
- |of builtin "." is simple and self-consistent.
-
- It is simple -- simple and erroneous. It is not consistent, because
- it differs with the actual behavior of the language. Again, when the
- language sees an expression "i" it must interpret this expressions as
- "reference to an object". The language cannot use different
- interpretations of the expression "i" depending on LHS verses RHS context
- because expressions in C/C++ do not depend on context.
-
- | To my mind, this "objection" -- that "." isn't like the overloadable
- |operators -- still stands.
-
- Correct your erroneous mind's understanding of the language, then your erroneous
- "objection" falls too.
-
- |> My operator.() proposal DOES NOT require forwarding functions unless
- |> the implementor of the reference class DESIRES to use forwarding functions.
- |
- |But the same can be said of the current situation -- you only have to
- |provide forwarding functions for those features of the target class
- |you desire to use. The "objection" still stands.
-
- You can say this -- because as time has show there is no way I can prevent
- you from saying erroneous statements. Your statement is false. One
- DOES NOT have to provide forwarding functions for those features of the
- target class one desires to use. On the Contrary one can CHOOSE to provide
- forwarding functions if desired. If NOT desired, then operator.() can
- be used to forward enmasse the target class functions requiring a target
- class object as an LHS, and "operator targetclass()" can be used for
- forward enmasse the target class functionality not requiring a target
- class object as an LHS, and within the Smart Ref class no forwarding
- functions are necessary because of implied this.
-
- Correct your errors and your objections do not continue to stand.
-
- |This is the same sort of semantic dancing as the previous point; the
- |fact is that, under your proposal, you must use a circumlocution to
- |access members of the smart reference object. The "objection" still
- |stands.
-
- Your statement is false again. No circumlocution is necessary because
- of "implied this." Correct your errors and your objection does not stand.
-
- |Thanks for your concern; my facts are in pretty good shape.
-
- If "facts" need not have any basis in reality, then they are indeed in
- "pretty good shape" because there is no way that such "facts" can be
- challenged.
-
- |That's not what I said. What I said was that the two alternatives I
- |mentioned did not have these three particular disadvantages of your
- |proposal but that I had not fully explored them.
-
- You also need to explore my proposal, so that you can discover that in
- fact the particular disadvantages you mention are not in fact disadvantages
- of my proposal, but rather errors in understanding on your part.
-
- |They may, in fact,
- |have far worse disadvantages than your proposal
-
- The most common disadvantage of these "other" approaches people have
- "thought" about is that simply they have no basis in the reality of
- the existing language. If one understands the language, and tries
- to write down how most of these "thoughts" would work, you simply find
- that they cannot work, given the context of the existing language, and
- how that existing language works. Languages and compilers aren't magic,
- "thoughts" people think up have to be implementable in the current context
- of how the language and compilers work. My proposal at least has the
- advantage that it can be so implemented.
-