Topic: Changing qualifier a.b to a->b and back


Author: bwh@kato.prl.ufl.edu (Brian Hook)
Date: 31 Aug 1994 18:10:38 GMT
Raw View
In article <MAV.94Aug30175731@gaia.cc.gatech.edu> mav@gaia.cc.gatech.edu (Maurizio Vitale) writes:

>   variables. By the same token, I just cannot stand having to add an
>   empty pait of parenthesis when calling a function with no arguments:
>   that's just in my way when I decide to change the implementation of
>   something between being a variable and being computed on the fly.
>   Again there's no reason why the compiler shouldn't figure out what to
>   do, and once again I don't think it should be in C++.

Hold up a second.  You're saying that the following code:

typedef void (*)() (*void_fnc)(); // syntax probably wrong but you know
                                  // what I mean
void_fnc afnc( void );

void blah()
{
void_fnc fnc = afnc;
}

Should mean what?  The compiler should assume that "fnc" is the RETURN
value of "afnc" because you didn't put in the parans but it should know
that you really 'meant' to call afnc()?

Or did I misread something?  If this was your suggestion, then the above
code demonstrates one potential problem...

Brian

--
+---------------------------------------------------------------------+
| Brian Hook            | Specializing in real-time 3D graphics       |
| Box 90315             |---------------------------------------------|
| Gainesville, FL 32607 | bwh@prl.ufl.edu                             |
+- "Style distinguishes excellence from accomplishment" - J. Coplien -+




Author: mav@gaia.cc.gatech.edu (Maurizio Vitale)
Date: 31 Aug 1994 19:07:57 GMT
Raw View
>>>>> "Brian" == Brian Hook <bwh@kato.prl.ufl.edu> writes:

  Brian> In article <MAV.94Aug30175731@gaia.cc.gatech.edu> mav@gaia.cc.gatech.edu (Maurizio Vitale) writes:
  >> variables. By the same token, I just cannot stand having to add an
  >> empty pait of parenthesis when calling a function with no arguments:
  >> that's just in my way when I decide to change the implementation of
  >> something between being a variable and being computed on the fly.
  >> Again there's no reason why the compiler shouldn't figure out what to
  >> do, and once again I don't think it should be in C++.

  Brian> Hold up a second.  You're saying that the following code:

  Brian> typedef void (*)() (*void_fnc)(); // syntax probably wrong but you know
  Brian>                                   // what I mean
  Brian> void_fnc afnc( void );

  Brian> void blah()
  Brian> {
  Brian> void_fnc fnc = afnc;
  Brian> }

  Brian> Should mean what?  The compiler should assume that "fnc" is
  Brian> the RETURN value of "afnc" because you didn't put in the
  Brian> parans but it should know that you really 'meant' to call
  Brian> afnc()?

This thread got way off the charter of comp.std.c++, imho, but I don't
feel confortable in redirecting it somewhere else without posting a
summary. Again, I do not advocate any changes to C++, and I'll be more
than happy when we'll have the C++ standard.

  Brian> Or did I misread something?  If this was your suggestion,
  Brian> then the above code demonstrates one potential problem...

It's obvious that any change to a language must be considered and
fighted upon much more than an occasional post allows for. In the case
above every problem stems from the fact that C and C++ silently
convert a function name into a pointer to the function. Now, what
about having to say, in the example above:

 void_fnc fnc = &afnc

and having the & operator on function having an effect instead of
generating some warning on the lines of "& on function, ignored"?
I don't claim this is going to solve every problem, but I'm pretty
confident it can be made work. Should it be made? Definitely not, but
not because it is not feasible (as some article on the . -> thread
implied).
--
    Maurizio Vitale
 _______________
|        _      |\   e-mail: mav@cc.gatech.edu     | How many times can
|  /|/| '_) | ) | |  voice:  (404) 881-6083 (home) | a man turn his head,
| | | |_(_|_|/  | |          (404) 853-9382 (work) | and pretend that he
|_______________| |                                | just doesn't see ?
 \_______________\|  fax:    (404) 853-9378        |  - Bob Dylan




Author: xmsb@borland.com (maurice s. barnum)
Date: Wed, 31 Aug 1994 19:24:48 GMT
Raw View
In article <34181i$jl7@crl4.crl.com>, Eric Smith <es@crl.com> wrote:
>In article <3404jk$pvp@engnews2.eng.sun.com>,
>Steve Clamage <clamage@Eng.Sun.COM> wrote:
>...
>>Perhaps you would like to allow a pointer to an object and the object itself
>>to be used interchangeably. This would make it impossible to distinguish
>...
>
...
>trivial change to the compiler would be to find the place where it decides
>to issue that error message, and make it decide instead to process the "."
>as if it were "->".
>
    adding yet another exception to "the rules" of the language,
    thereby making the language more complicated to learn (more
    things to cover) and just a whee bit harder for the compiler
    to parse (as if there are any non-broken C++ parsers in existence
    to begin with).

    for no gain whatsoever.  Oh sure, there is a gain for those who
    cannot understand/remember/look up the distinction between
    "select member b from object a" and "derefence pointer a, and
    then select member b from that object".  Two quite non-equivalent
    operations.  So a few people with thick skulls or poor reading
    skills are saved the trouble of learning the language, let's
    add more baggage to an already um... "volumetrically enhanced"
    language spec?

    no thanks.  objects != pointers to objects.  If you want
    something else, then use something else.


--
Maurice S. Barnum               ==    I speak for me, not my employer.
xmsb@genghis.borland.com        ||    "There is no confusion like the
mosigbit@deeptht.armory.com     ||    confusion of a simple mind."
mbarnum@nyx.cs.du.edu           ==       -- F. Scott Fitzgerald




Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Wed, 31 Aug 1994 19:55:18 GMT
Raw View
In article <MAV.94Aug30175731@gaia.cc.gatech.edu> mav@cc.gatech.edu writes:
>
>incorporated in C++, only that I cannot see any reason for having two
>different operators for invoking methods and accessing member
>variables. By the same token, I just cannot stand having to add an
>empty pait of parenthesis when calling a function with no arguments:
>that's just in my way when I decide to change the implementation of
>something between being a variable and being computed on the fly.
>Again there's no reason why the compiler shouldn't figure out what to
>do, and once again I don't think it should be in C++.

 In that case, why not use Eiffel?

 If you chose to use __C__ plus plus you will have to
live with the vagaries of C. Too bad. Its your choice.

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189




Author: es@crl.com (Eric Smith)
Date: 31 Aug 1994 16:30:28 -0700
Raw View
In article <CvEz9C.2Lz@borland.com>,
maurice s. barnum <xmsb@borland.com> wrote:
>    for no gain whatsoever.  Oh sure, there is a gain for those who
>    cannot understand/remember/look up the distinction between
>    "select member b from object a" and "derefence pointer a, and
>    then select member b from that object".  Two quite non-equivalent
>    operations.  So a few people with thick skulls or poor reading
>    skills are saved the trouble of learning the language, let's
>    add more baggage to an already um... "volumetrically enhanced"
>    language spec?

65.flamo(-,...,*)static const {flumfla::bugah+*!=";";}; // future baggage?

You missed the main gains: "." is easier to type than "->".  The "-"
doesn't use the shift key, and the ">" does, so "->" is like a tongue
twister.  And some lines of code in deeply nested loops might extend
past the right margin as a result of using a bunch of two-character
"->"s instead of a bunch of "."s in the line.  And the "->" visually
clashes with names using underlines.

And it's not a matter of adding a bunch of baggage to an already
overloaded (no pun intended) language.  It's a trivial addition,
far more trivial than most of the other additions made in recent
years.  It's so trivial, compiler vendors who offer optional extensions
to the language will probably throw this one in too, and have the user
select the whole package of extensions with one compiler switch, and
only mention this one with a single sentence in their manual.

So, "no gain whatsoever" is not quite right.  It would be closer to the
mark to say "no loss whatsoever."





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 30 Aug 1994 20:25:24 GMT
Raw View
In article 94Aug29101310@gaia.cc.gatech.edu, mav@gaia.cc.gatech.edu (Maurizio Vitale) writes:
>>>>>> "Ronald" == Ronald F Guilmette <rfg@netcom.com> writes:
>
>  Ronald> In article <33b7ks$6fv@flclcnsa.clc.gmeds.com> bhenk02@cps.plnin.gmeds.com writes:
>  >> I always find it somewhat frustrating that C++ (and C for that matter)
>  >> does not "understand" that a.b and a->b (to me) mean the same thing.
>
>  Ronald> They DON'T mean the same thing... but if you want to program
>  Ronald> in a language which tries to pretend that they do, try Ada.
>
>They don't mean the same thing in the very same way that 2 + 2 and 2.0
>+ 2.0 don't mean the same thing. They both mean to use the member
>named `b' inside the object denoted by `a'.

No, they do not. In the first case, 'a' must denote an object of a stuct type
(struct, union, or class). In the second case, 'a' must denote an object of
pointer type. The arrow is only a shorthand notation allowing "a->b" as a
substitute for "(*a).b" (except for operator overloading, but that's a side issue).

Perhaps you would like to allow a pointer to an object and the object itself
to be used interchangeably. This would make it impossible to distinguish
operations on pointers from operations on the object pointed to. After all,
a pointer is an object in its own right.

An alternative language design is to have only pointers to objects. You write
what appear to be object references, but they are really references via
pointers in all cases. There is then only one notation. Add garbage collection,
and you have, well, Smalltalk, more or less. Whatever the relative advantages
and disadvantages of such a language design, it isn't C++.

---
Steve Clamage, stephen.clamage@eng.sun.com






Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 30 Aug 1994 20:38:21 GMT
Raw View
In article 94Aug29124710@galaga.lna.logica.com, michaelc@lna.logica.com writes:
>>>>>> "mav" == Maurizio Vitale <mav@gaia.cc.gatech.edu> writes:
>
>    mav> It is true that C++ follows the C tradition on this, but there's no
>    mav> technical reason to this as I don't believe there's a single case in
>    mav> which the compiler cannot figure out what to do.
>
>The ANSI C people decided to let the compiler be smart enough to understand
>that `pf()' is the same as `(*pf)()'.  Given that "prior art," letting the
>compiler decide that `ps.m' is the same as `ps->m' seems natural.

That is not the same situation at all. An expression which evaluates to a
function is replaced by its address, and the type becomes pointer-to-function.
When you use the function-call operator "()", it assumes the operand on the
left is a pointer to a function, and calls the function at that address.

Thus, given
 void foo();
 void (*fp)() = foo;
we can write a call to function foo as "foo()", "fp()", or "(*fp)()", because
they all mean the same thing. We can also write "(****************fp)()"
because at each stage of evaluating the pointer dereferences, the dereference
has a function type, which is replaced by the address of the function. Thus,
any number of "*" operators may be concatenated, having no additional effect.

This funny rule was introduced as a way of regularizing existing practice in
C function calls. It means that you can never have a function object, since
anything that looks like a function gets turned immediately into its address.
But that is exactly the rule in C and C++: there are no function objects. The
only thing you can do with a function is take its address and call it, and
these are amazingly enough the only operations supported as a consequence of
the rewriting rules above.

Such rules would not support distinguishing an object from a pointer to the
object. As I said in another post, a possible language design is one which does
not distinguish between a data object and what points to it, but that isn't
C or C++.
---
Steve Clamage, stephen.clamage@eng.sun.com






Author: mav@gaia.cc.gatech.edu (Maurizio Vitale)
Date: 30 Aug 1994 21:57:31 GMT
Raw View
>>>>> "Steve" == Steve Clamage <clamage@Eng.Sun.COM> writes:

  Steve> Perhaps you would like to allow a pointer to an object and
  Steve> the object itself to be used interchangeably. This would make
  Steve> it impossible to distinguish operations on pointers from
  Steve> operations on the object pointed to. After all, a pointer is
  Steve> an object in its own right.

Only when accessing members. Everywhere else we can keep the
distinction between pointers and objects until we won't have compilers
smart enough to figure out when to use pointers and when to use
objects. That day we won't hear about pointers more than about the
register directive today: something compilers can throw away because
they know they can do a better job than the average programmer.

  Steve> An alternative language design is to have only pointers to
  Steve> objects. You write what appear to be object references, but
  Steve> they are really references via pointers in all cases. There
  Steve> is then only one notation. Add garbage collection, and you
  Steve> have, well, Smalltalk, more or less. Whatever the relative
  Steve> advantages and disadvantages of such a language design, it
  Steve> isn't C++.

Most definitly, and I'm not claiming that this feature should be
incorporated in C++, only that I cannot see any reason for having two
different operators for invoking methods and accessing member
variables. By the same token, I just cannot stand having to add an
empty pait of parenthesis when calling a function with no arguments:
that's just in my way when I decide to change the implementation of
something between being a variable and being computed on the fly.
Again there's no reason why the compiler shouldn't figure out what to
do, and once again I don't think it should be in C++.
--
    Maurizio Vitale
 _______________
|        _      |\   e-mail: mav@cc.gatech.edu     | How many times can
|  /|/| '_) | ) | |  voice:  (404) 881-6083 (home) | a man turn his head,
| | | |_(_|_|/  | |          (404) 853-9382 (work) | and pretend that he
|_______________| |                                | just doesn't see ?
 \_______________\|  fax:    (404) 853-9378        |  - Bob Dylan




Author: robtcram@crl.com (Robert H. Cram)
Date: 30 Aug 1994 22:28:23 -0700
Raw View
Steve Clamage (clamage@Eng.Sun.COM) wrote:
: In article 94Aug29101310@gaia.cc.gatech.edu, mav@gaia.cc.gatech.edu (Maurizio Vitale) writes:
: >>>>>> "Ronald" == Ronald F Guilmette <rfg@netcom.com> writes:
: >
: >  Ronald> In article <33b7ks$6fv@flclcnsa.clc.gmeds.com> bhenk02@cps.plnin.gmeds.com writes:
: >  >> I always find it somewhat frustrating that C++ (and C for that matter)
: >  >> does not "understand" that a.b and a->b (to me) mean the same thing.
: >
: >  Ronald> They DON'T mean the same thing... but if you want to program
: >  Ronald> in a language which tries to pretend that they do, try Ada.
: >
: >They don't mean the same thing in the very same way that 2 + 2 and 2.0
: >+ 2.0 don't mean the same thing. They both mean to use the member
: >named `b' inside the object denoted by `a'.

: No, they do not. In the first case, 'a' must denote an object of a stuct type
: (struct, union, or class). In the second case, 'a' must denote an object of
: pointer type. The arrow is only a shorthand notation allowing "a->b" as a
: substitute for "(*a).b" (except for operator overloading, but that's a side issue).

: Perhaps you would like to allow a pointer to an object and the object itself
: to be used interchangeably. This would make it impossible to distinguish
: operations on pointers from operations on the object pointed to. After all,
: a pointer is an object in its own right.

: An alternative language design is to have only pointers to objects. You write
: what appear to be object references, but they are really references via
: pointers in all cases. There is then only one notation. Add garbage collection,
: and you have, well, Smalltalk, more or less. Whatever the relative advantages
: and disadvantages of such a language design, it isn't C++.

: ---
: Steve Clamage, stephen.clamage@eng.sun.com






Author: es@crl.com (Eric Smith)
Date: 30 Aug 1994 23:30:10 -0700
Raw View
In article <3404jk$pvp@engnews2.eng.sun.com>,
Steve Clamage <clamage@Eng.Sun.COM> wrote:
...
>Perhaps you would like to allow a pointer to an object and the object itself
>to be used interchangeably. This would make it impossible to distinguish
...

It's trivial to allow pointer.member as shorthand for pointer->member, and
does not involve any such complications as being able to use the object and
pointer interchangeably.  Right now it returns an error message.  The
trivial change to the compiler would be to find the place where it decides
to issue that error message, and make it decide instead to process the "."
as if it were "->".