Topic: ctor/dtor behaviour for ordinary member functions?


Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Tue, 1 Mar 1994 02:36:42 GMT
Raw View
maxtal@physics.su.OZ.AU (John Max Skaller) writes:
>imp@boulder.parcplace.com (Warner Losh) writes:
>>pete@borland.com (Pete Becker) writes:
>>>
>>> class Derived : public Base
>>> {
>>> typedef Base inherited;
>>> public:
>>>  void foo() { inherited::foo(); }
>>> };
>>
>>Might I point out that this fails the "Change it in one place" test.
>>A language feature would be able to change it one place (the public
>>Base) and it would ripple through all other places where it was
>>needed.  This creative use of the language requires two changes.  For
>>large systems, this is unacceptable, especailly if a new class gets
>>inserted between Derived and Base (and there are a non-trivial number
>>of Derived classes from base that need this change).
>
> Twaddle :-)
>
> If a new class get inserted between a Derived and
>Base, the call may or may not have to go to the inserted
>class or remain a call to the original base.

Nonsense.  If a new class `Intermediate' gets inserted between Derived and
Base, all the calls which were via `inherited::' will have to
call Intermediate::foo() if Intermediate has overridden foo().
Calls which would have to remain calls to the original Base::foo()
even if Intermediate has overriden foo() should be written as
`Base::foo()' in the first place, not as `inherited::foo()'.

> "Inherited" sucks anyhow. It only makes sense
>for single inheritance.

Complete twaddle.  It makes perfect sense for multiple inheritence.

In the case of

 struct Derived1 : Base1, Base2 {
  void foo() { inherited::foo(); }
 };

then the call to inherited::foo() has exactly the same behaviour
as a call to foo() would have if Derived didn't override foo(),
as in the following example:

 struct Derived2 : Base1, Base2 {
  void bar() { foo(); }
 };

--
Fergus Henderson - fjh@munta.cs.mu.oz.au




Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Sun, 20 Feb 1994 22:55:20 GMT
Raw View
In article <27668@alice.att.com> bs@alice.att.com (Bjarne Stroustrup) writes:
>hall_j@sat.mot.com (Joseph Hall @ Motorola Inc., Satellite Communications) writes
>
> > The deficiency of C++ in this
> > area is that there is no syntax that allows you to access
> > overridden/inherited members without using class names.  Symantec's
> > support for the "inherited" keyword is IMHO a Good Thing and I
> > am hoping that something like this will eventually find its way
> > into the standard.
>
>``inherited::'' was proposed to the committee and was rejected.
>
>I strongly feel that compiler purveyers should refrain from providing
>``minor features and conveniences'' that has not been approved by the
>committee, and that they should especially refrain from providing
>features explicitly rejected.
>
>I don't think it is in the interest of users to have such non-standard
>features because such features lock them into a single supplier.

 I agree but there is a flip side of the coin.
While the committee may be slow or unwilling to provide
certain facilities, vendors of compilers for diverse
systems are forced to provide non-standard extensions
that lock users in anyhow. So it doesnt make so
much difference, once you're locked in, that you use
other vendor extensions.

 There are also proposals that the committee
rejected for reasons of timimg of the Standard, or lack of
existing practice <grin> or relationship with other Standards
that do not constrain vendors. In this case, the proposals
make an excellent basis for vendors to provide extensions,
hopefully several vendors will agree to provide similar
extensions that can subsequently be Standardised.

 Any vendor with the courage to provide object
closures so that callbacks to member functions could work,
would solve major problems for those working in
Windowing environments. For example.

 Responsible vendors provide compatibility switches,
so you can check the portability of your code.


--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,      CSERVE:10236.1703
        6 MacKay St ASHFIELD,     Mem: SA IT/9/22,SC22/WG21
        NSW 2131, AUSTRALIA




Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Sun, 20 Feb 1994 23:04:22 GMT
Raw View
In article <CKtu90.Hrv@boulder.parcplace.com> imp@boulder.parcplace.com (Warner Losh) writes:
>In article <1994Feb5.174559.5233@borland.com> pete@borland.com (Pete
>Becker) writes:
>> class Base
>> {
>> public:
>>  void foo();
>> };
>>
>> class Derived : public Base
>> {
>> typedef Base inherited;
>> public:
>>  void foo() { inherited::foo(); }
>> };
>
>Might I point out that this fails the "Change it in one place" test.
>A language feature would be able to change it one place (the public
>Base) and it would ripple through all other places where it was
>needed.  This creative use of the language requires two changes.  For
>large systems, this is unacceptable, especailly if a new class gets
>inserted between Derived and Base (and there are a non-trivial number
>of Derived classes from base that need this change).

 Twaddle :-)

 If a new class get inserted between a Derived and
Base, the call may or may not have to go to the inserted
class or remain a call to the original base. The above
method defaults to the original base if you dont typedef
"inherited" in the new derived class.

 "Inherited" sucks anyhow. It only makes sense
for single inheritance.


--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,      CSERVE:10236.1703
        6 MacKay St ASHFIELD,     Mem: SA IT/9/22,SC22/WG21
        NSW 2131, AUSTRALIA




Author: imp@boulder.parcplace.com (Warner Losh)
Date: Wed, 9 Feb 1994 21:42:56 GMT
Raw View
In article <CRAFFERT.94Feb8101722@nostril.lehman.com>
craffert@nostril.lehman.com (Colin Owen Rafferty) writes:
>So what do you do when `derived' is multiply inherited?
> void derived::foo(void)
> {
>  inherited::foo(); // which foo() do I call?
> }

Same answer as the following:

void foo(char *);
void foo(int);

/* ... */
foo( 0 );

Both should produce an error.  The latter complains that it is
ambiguous, so should the former.  This doesn't make overloaded
functions less useful.  Nor should your example be used to prove that
inherited:: is less useful because the possibility for ambiguity
exists.

Warner
--
Warner Losh  imp@boulder.parcplace.COM ParcPlace Boulder
I've almost finished my brute force solution to subtlety.




Author: pete@borland.com (Pete Becker)
Date: Wed, 9 Feb 1994 22:55:06 GMT
Raw View
In article <CKz8BK.MIA@boulder.parcplace.com>,
Warner Losh <imp@boulder.parcplace.com> wrote:
>In article <CRAFFERT.94Feb8101722@nostril.lehman.com>
>craffert@nostril.lehman.com (Colin Owen Rafferty) writes:
>>So what do you do when `derived' is multiply inherited?
>> void derived::foo(void)
>> {
>>  inherited::foo(); // which foo() do I call?
>> }
>
>Same answer as the following:
>
>void foo(char *);
>void foo(int);
>
>/* ... */
>foo( 0 );
>
>Both should produce an error.  The latter complains that it is
>ambiguous, so should the former.  This doesn't make overloaded
>functions less useful.  Nor should your example be used to prove that
>inherited:: is less useful because the possibility for ambiguity
>exists.
>

 This seems like a rather strained analogy. A keyword "inherited"
will not ever work with multiple inheritance. That makes it almost useless to
any serious C++ programmer. When you add to that the fact that it's trivial
to create your own much more flexible version it becomes a feature that's
pointless.
 -- Pete




Author: hall_j@sat.mot.com (Joseph Hall)
Date: Fri, 11 Feb 1994 03:12:58 GMT
Raw View
Seems it was pete@borland.com (Pete Becker) who said:
> This seems like a rather strained analogy. A keyword "inherited"
>will not ever work with multiple inheritance. That makes it almost useless to
>any serious C++ programmer.

I think you will find that there are a few people who are considered
"serious" C++ programmers who would still contemplate using features that
don't work perfectly with MI.  In fact I steer clear of MI in most
cases because of the bugs it elicits in many compilers (in general
I am seriously concerned about the portability of my code).

It seems obvious to *me* that in most cases inherited:: WILL work
with MI.  If you are using fat interfaces with MI you have other
worse problems.

>When you add to that the fact that it's trivial
>to create your own much more flexible version it becomes a feature that's
>pointless.

It's not trivial when you consider the problems of maintaining the
"much more flexible" handrolled version when classes are inserted
in the hierarchy.

I believe the committee was wrong to reject inherited::, but I
doubt that these were precisely their reasons.  (I saw Bjarne's
followup to my original post.)

inherited:: works perfectly well almost all of the time, and the
remaining imperfect cases are easily diagnosed.

--
Joseph Nathan Hall | "Fetch the comfy chair!"
Software Architect |
Gorca Systems Inc. |                 joseph@joebloe.maple-shade.nj.us (home)
(on assignment)    | (602) 732-2549 (work)  Joseph_Hall-SC052C@email.mot.com




Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Fri, 11 Feb 1994 12:50:04 GMT
Raw View
jazz@hal.com (Jason Zions) writes:

>hall_j@sat.mot.com (Joseph Hall) writes:
>
>>   derived::foo()
>>   {
>>       // do something
>>       inherited::foo(); // call base::foo(), or whatever foo()
>>      // this class inherited
>>   }
>
>But whoever developed the "derived" class knows darn well it was derived
>from base; when providing an implementation of the derived::foo() method
>there's no lack of information as to precisely which class it was derived
>from.

Sure, but it's a maintenance issue, not a development issue.
The problem comes when you want to insert a new class in between
base and derived, and the assumption which was wired into the
code by the original programmer becomes wrong.

>Besides, in the context of multiple inheritence, which base class would
>"inherited" resolve to?

If only one of the base classes contained a foo() member, then
it would resolve to that one; otherwise it would be an ambiguity
error.

>In short - reserving "inherited" as a keyword is a bad idea, and it buys you
>nothing.

I disagree.  It allows you to reduce the number of places in your
code which contain assumptions about the class hierarchy, thus
making your code more resilient to change.

It is true that in the case of single inheritance, it doesn't buy
you much, because you can use the `typedef base inherited;' trick.
But that trick won't work in the case of multiple inheritence.

It might be reasonable to conclude that on balance, what is
gained is not worth the increase in language complexity.
But to say that "it buys you nothing" is just simply not true.

--
Fergus Henderson - fjh@munta.cs.mu.OZ.AU




Author: jimad@microsoft.com (Jim Adcock)
Date: Fri, 11 Feb 1994 20:49:41 GMT
Raw View
In article <27668@alice.att.com> bs@alice.att.com (Bjarne Stroustrup) writes:
|I strongly feel that compiler purveyers should refrain from providing
|``minor features and conveniences'' that has not been approved by the
|committee, and that they should especially refrain from providing
|features explicitly rejected.
|
|I don't think it is in the interest of users to have such non-standard
|features because such features lock them into a single supplier. You
|may be perfectly happy with your supplier today, but many things can
|change over the years and you or your customers may want to retain
|freedom of choice. Therefore, a user should think very hard
|before prasing a compiler supplier for providing a non-essential
|non-standard feature - however ``neat.'' Such praise encourages
|them to lock you in.

I strongly disagree with this position.  It has also been in the
tradition of the C family of langauges that vendors were *allowed*
to extend their compilers.  Likewise it was always in the tradition of
the C family of langauges that users were *allowed* to write vendor-
specific, cpu-specific, or system-specific code.  In fact little or
no modern useful C++ code can be written without making *some* assumptions
specific to the vendor/cpu/system that are being targetted.

The assumption being that the *user* is a mature intelligent professional
adult who can decide for themself to what extent they want to tie
their code to a particular vendor/cpu/system, whether for performance,
convenience, laziness, whatever, verses to what extent they want to
pay the price to write portable code.  The intent of the C family
of languages is to *allow* programmers the choice to write portable code,
not to force that choice upon them.

The reason that this distinction is important is because fundamentally
what the committee agrees upon for "The C++ Language" is not what is
good, not what is right, but simply what a bunch of people *could*
get together and *agree* upon.  Thus what the standard will specify
is necessarily that subset of "The C++ Language" that *could* be
agreed upon.  Anything that *could not* be agreed upon is then not
part of "The C++ Language."

Ultimately, "C++" must grow and take on new directions, or it must die.
Two such early examples of how "C" grew and took on new directions
were the two vendor-specific extensions called "Objective-C" and
"C++".  There was and continues to be disagreement about *which* set
of extensions was better.  If it was then up to a committee to decide *which*
set of extensions to put into "C" the answer would be "neither" -- because
a "C" commitee could not decide *which.*  Eventually one of these vendor-specific
extensions became successful enough to become recognized as a separate dialect
of "C" in its own right.  Early adopters of that particular set of extensions
arguably made a "good" decision in choosing to use those vendor-specific
set of extensions.  *They* chose to use those set of extensions because
*even though* they knew they were locking themselves into one particular
supplier [which certainly *no one* was happy with!] *they* decided it
was worth taking the risk.

In the future C++ will undoubtable be extended in many vendor-specific
ways as vendors try to add value and distinctness to their offerings.
Garbage collection, *real* type safety, OODB extensions, multiprocessing,
better numerical support, etc, are all oft-mentioned topics for extensions.
Vendors need the *choice* to offer these kinds of extensions, and customers
need to *choose* whether or not it is worth their while to use them.
No one need try to dictate these decisions to the marketplace.  The
marketplace can decide for itself -- while at the same time maintaining
that *subset* of common functionality in every compiler known as
"The C++ Language."




Author: bobkf@news.delphi.com (BOBKF@DELPHI.COM)
Date: 12 Feb 1994 15:48:13 -0500
Raw View
jimad@microsoft.com (Jim Adcock) writes:

>In article <27668@alice.att.com> bs@alice.att.com (Bjarne Stroustrup) writes:
>|I strongly feel that compiler purveyers should refrain from providing
>|``minor features and conveniences'' that has not been approved by the
>|committee, and that they should especially refrain from providing
>|features explicitly rejected.
>|
>|I don't think it is in the interest of users to have such non-standard
>|features because such features lock them into a single supplier. You
>|may be perfectly happy with your supplier today, but many things can
>|change over the years and you or your customers may want to retain
>|freedom of choice. Therefore, a user should think very hard
>|before prasing a compiler supplier for providing a non-essential
>|non-standard feature - however ``neat.'' Such praise encourages
>|them to lock you in.

>I strongly disagree with this position.  It has also been in the
>tradition of the C family of langauges that vendors were *allowed*
>to extend their compilers.  Likewise it was always in the tradition of
>the C family of langauges that users were *allowed* to write vendor-
>specific, cpu-specific, or system-specific code.  In fact little or
>no modern useful C++ code can be written without making *some* assumptions
>specific to the vendor/cpu/system that are being targetted.

I disagree, too, but not for that reason. It is laughable to take the
position that vendors should implement strictly "pure" C++ when no such
animal exists. One has only to look at the implementations of templates
and exception handling that exist today to see that it is not possible to
implement the ever-growing C++ language without extending it. What does a
programmer have to write to ensure that templates are expanded? When an
exception is thrown while an object created by operator new is under
construction, what happens to the memory allocated for the object? One
might throw the question of adherence to the specification back to the
committee: please stop inventing new language and specify the one you have
already invented.

Bob Foster
objfactory@aol.com





Author: bs@alice.att.com (Bjarne Stroustrup)
Date: 13 Feb 94 04:13:49 GMT
Raw View


jimad@microsoft.com (Jim Adcock) writes

 > In article <27668@alice.att.com> bs@alice.att.com (Bjarne Stroustrup) writes:

 > |I strongly feel that compiler purveyers should refrain from providing
 > |``minor features and conveniences'' that has not been approved by the
 > |committee, and that they should especially refrain from providing
 > |features explicitly rejected.
 > |
 > |I don't think it is in the interest of users to have such non-standard
 > |features because such features lock them into a single supplier. You
 > |may be perfectly happy with your supplier today, but many things can
 > |change over the years and you or your customers may want to retain
 > |freedom of choice. Therefore, a user should think very hard
 > |before prasing a compiler supplier for providing a non-essential
 > |non-standard feature - however ``neat.'' Such praise encourages
 > |them to lock you in.

 > I strongly disagree with this position.  It has also been in the
 > tradition of the C family of langauges that vendors were *allowed*
 > to extend their compilers.  Likewise it was always in the tradition of
 > the C family of langauges that users were *allowed* to write vendor-
 > specific, cpu-specific, or system-specific code.  In fact little or
 > no modern useful C++ code can be written without making *some* assumptions
 > specific to the vendor/cpu/system that are being targetted.

You might be surprised that I agree with that.

 > The assumption being that the *user* is a mature intelligent professional
 > adult who can decide for themself to what extent they want to tie
 > their code to a particular vendor/cpu/system, whether for performance,
 > convenience, laziness, whatever, verses to what extent they want to
 > pay the price to write portable code.  The intent of the C family
 > of languages is to *allow* programmers the choice to write portable code,
 > not to force that choice upon them.

and nothing I said in that message disagreed with this either.

 > The reason that this distinction is important is because fundamentally
 > what the committee agrees upon for "The C++ Language" is not what is
 > good, not what is right, but simply what a bunch of people *could*
 > get together and *agree* upon.  Thus what the standard will specify
 > is necessarily that subset of "The C++ Language" that *could* be
 > agreed upon.  Anything that *could not* be agreed upon is then not
 > part of "The C++ Language."

Exactly, and it is very important that users know exactly what constitutes
the C++ language.

 > Ultimately, "C++" must grow and take on new directions, or it must die.

Of course

 > Two such early examples of how "C" grew and took on new directions
 > were the two vendor-specific extensions called "Objective-C" and
 > "C++".

That is not the way I see it. C++ was and is a new language closely related
to C. Calling it a ``vendor-specific extension'' would be a confusion.
Until PC compiler vendors started shipping combined C and C++ producets,
nobody supplied a C compiler with added ``++ features.'' Even now, the
compiler suppliers clearly label their products ``C++.'' This prevents
the confusion and the accidental/sneaky lock-in that I would like to
discourage.

There will be always the option of choosing one language over another.

 > There was and continues to be disagreement about *which* set
 > of extensions was better.  If it was then up to a committee to decide *which*
 > set of extensions to put into "C" the answer would be "neither" -- because
 > a "C" commitee could not decide *which.*  Eventually one of these vendor-specific
 > extensions became successful enough to become recognized as a separate dialect
 > of "C" in its own right.

Again, this is not the way I read history. I designed and implemented a new
language, I published about it, and first one then several implementations
were made available to users.

Almost ten years after I started this work, someone (not I) asked the ANSI C
committee if it would like make a C++ standard. That committee declined -
as I would have expected it to and quite properly. The people wanting a C++
standard (this time with my support) approached the appropriate ANSI (and
later ISO) body and asked permission to start standardizing a new language
called C++ (as opposedto C). This started the standardization of C++ and
the C++ committee reaffirmed my design guideline of keeping C++ ``as close
to C as possible - but no closer.''

 > Early adopters of that particular set of extensions
 > arguably made a "good" decision in choosing to use those vendor-specific
 > set of extensions.  *They* chose to use those set of extensions because
 > *even though* they knew they were locking themselves into one particular
 > supplier [which certainly *no one* was happy with!] *they* decided it
 > was worth taking the risk.

!!

 > In the future C++ will undoubtable be extended in many vendor-specific
 > ways as vendors try to add value and distinctness to their offerings.

Extension will undoubtedly happen.

Some extensions will be genuinely needed, say to deal with awkward machine
architectures (like the `near' and `far' extensions to C). I have little
against such extensions. I prefer to do without them, but as long as they
don't interfere seriously with the logic of the language and as long as
they are highly visible they don't do much harm. People will know they are
dealing with something non-standard. A really important aspect of `near'
and `far' is/was that the could be #defined away when and where they were
not needed. The language of the ANSI C standard was crafted not to obstruct
such extensions and the ANSI C++ wordage will follow. (This is actually
somewhat tricky, for example, someone once presented me with the ``useful
extension'' of being able to access private data from every function in
the program - in other words they hadn't bothered to implement access
control. I didn't consider that acceptable.)

Some extensions are less benign. For example, a unique feature that doesn't
require a keyword and is only marked as a ``non-standard extension'' deep
in some multi-volume vendor documentation but present in code example can
easily trick the user into writing non-standard code without intending to
do so. By the time the programmer notices, it may have become rather hard
to switch into Standard C++. An example of this would be a compiler that
quietly accepted overloading based on the return type under its default
setting. I would like to discourage this kind of ``invisible extension.''
The extension that caused me to post the message you quoted, ``inherited::,''
is of this general character, though marginally less sneaky because it
involves a keyword.

An extension can cause problems even if it is highly visible. For example,
a vendor can lock in users (or force other vendors to adopt a non-standard
extension) by making access to a critical system resource or library
dependent on the non-standard feature. Naturally, I don't like that either.

 > Garbage collection, *real* type safety, OODB extensions, multiprocessing,
 > better numerical support, etc, are all oft-mentioned topics for extensions.
 > Vendors need the *choice* to offer these kinds of extensions, and customers
 > need to *choose* whether or not it is worth their while to use them.

Experiments will happen, and some will succeed and the features that result
will become common. However, I think that it is in the interest of both the
suppliers and the users for such features to be clearly optional, be major,
and as far as possible the result of an open and public process. I don't
see a ``feature war'' among the suppliers fought by adding as many neat
features as can be crammed into the next release as being in anyone's
interest.

In general, I encourage people to look to libraries rather than language
extensions. More often than not there seem to be a choice.

Of the extensions you mention, I think that GC is allowed by the current
rules and I would like to see GC support as long as it isn't closely tied
to proprietary extensions or serious restrictions of what features that
can coexist with GC. Most improved numerical support and concurrency
support fall into the same catagory. The OODB extensions are only relevant
if you actually use an OODB and there is an effort among the OODB purveyers
to provide a standard interface to all the databases - exactly to avoid
lock-in and preserve the choice for users.

The issue of extensions is never going to be easy or clear cut.

 > No one need try to dictate these decisions to the marketplace.  The
 > marketplace can decide for itself -- while at the same time maintaining
 > that *subset* of common functionality in every compiler known as
 > "The C++ Language."

The marketplace can indeed decide for itself and nobody can ``dictate.''
Governments try, but not always successfully. Large corporations occationally
has such aspirations also. However, there are many players in the marketplace
and my sympaties rest primarily with the users. Suppliers usually have an
easier time looking after their own interests.

One aim of standards is to provide a level playing field in the interest
of general commerce. As I understand it, that will in the long run help
both purveyers and users.

 - Bjarne




Author: dag@control.lth.se (Dag Bruck)
Date: 13 Feb 1994 10:54:55 GMT
Raw View
>>>>> On 12 Feb 1994 15:48:13, bobkf@news.delphi.com (BOBKF@DELPHI.COM) said:

>In article <27668@alice.att.com> bs@alice.att.com (Bjarne Stroustrup) writes:
>|I strongly feel that compiler purveyers should refrain from providing
>|``minor features and conveniences'' that has not been approved by the
>|committee, and that they should especially refrain from providing
>|features explicitly rejected.

> It is laughable to take the
> position that vendors should implement strictly "pure" C++ when no such
> animal exists.

Well, you can at least ask vendors not to implement features that the
committee has considered and rejected, for example, keyword
"inherited."  It has apparently to be repeated.

    -- Dag




Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Mon, 14 Feb 1994 04:24:49 GMT
Raw View
pete@borland.com (Pete Becker) writes:

>Warner Losh <imp@boulder.parcplace.com> wrote:
>>craffert@nostril.lehman.com (Colin Owen Rafferty) writes:
>>>So what do you do when `derived' is multiply inherited?
>>
>>Same answer as the following:
>>
>>void foo(char *);
>>void foo(int);
>>
>>/* ... */
>>foo( 0 );
>>
>>Both should produce an error.  The latter complains that it is
>>ambiguous, so should the former.  This doesn't make overloaded
>>functions less useful.  Nor should your example be used to prove that
>>inherited:: is less useful because the possibility for ambiguity
>>exists.
>
> This seems like a rather strained analogy. A keyword "inherited"
>will not ever work with multiple inheritance. That makes it almost useless to
>any serious C++ programmer.

Huh?  A keyword "inherited" WILL work with multiple inheritence.
It seems that some people are having trouble understanding this
point, so let me give an example:

 struct Base1 {
  foo();
 };
 struct Base2 {
  bar();
 };
 struct Derived : Base1, Base2 {
  baz() {
   inherited::foo(); // calls Base1::foo();
   inherited::bar(); // calls Base2::foo();
  }
 };

This example, like the vast majority of real-world examples where
`inherited::' might be used, just simply WORKS.

The analogy isn't strained at all.

Note that to simulate this example using typedefs requires introducing
a new intermediate class, which is a pain and is in general
undesireable (especially since constructors would have to be manually
forwarded).  Thus it is the typedef work-around that falls down in the
case of multiple inheritence, NOT the language extension proposal.

>When you add to that the fact that it's trivial
>to create your own much more flexible version it becomes a feature that's
>pointless.

I'm perfectly willing to acknowlegde that the benefit is relatively
small and may not be worth the increase in language complexity.  But I
wish people would stop saying that it "will not ever work" or that it
is "pointless".  The fact is that it WOULD work, and that it WOULD have
some benefit.

I also take issue with your claim that the hand-crafted versions are
"much more flexible".  In what way are they more flexible, and
how does this help?  It is in fact very UNDESIREABLE for the meaning
of `inherited::' to be flexible.

(Apologies if all those capital letters are a bit noisy ;-).

--
Fergus Henderson - fjh@munta.cs.mu.OZ.AU




Author: grumpy@cbnewse.cb.att.com (Paul J Lucas)
Date: Sat, 5 Feb 1994 17:23:06 GMT
Raw View


Author: pete@borland.com (Pete Becker)
Date: Sat, 5 Feb 1994 17:45:59 GMT
Raw View
In article <1994Feb5.000546.2964@sat.mot.com>,
Joseph Hall <hall_j@sat.mot.com> wrote:
>
>Paul brings up a good point here.  The deficiency of C++ in this
>area is that there is no syntax that allows you to access
>overridden/inherited members without using class names.

 class Base
 {
 public:
  void foo();
 };

 class Derived : public Base
 {
 typedef Base inherited;
 public:
  void foo() { inherited::foo(); }
 };

 -- Pete




Author: craffert@nostril.lehman.com (Colin Owen Rafferty)
Date: Tue, 8 Feb 1994 15:17:22 GMT
Raw View
In article <1994Feb5.000546.2964@sat.mot.com> hall_j@sat.mot.com (Joseph Hall) writes:
> Seems it was grumpy@cbnewse.cb.att.com (Paul J Lucas) who said:
>> ...

> Paul brings up a good point here.  The deficiency of C++ in this
> area is that there is no syntax that allows you to access
> overridden/inherited members without using class names.  Symantec's
> support for the "inherited" keyword is IMHO a Good Thing and I
> am hoping that something like this will eventually find its way
> into the standard.

> E.g.:

> base::foo()
> {
>     // do something
> }

> derived::foo()
> {
>     // do something
>     inherited::foo(); // call base::foo(), or whatever foo()
>                       // this class inherited
> }

So what do you do when `derived' is multiply inherited?

 class base1 {
  virtual void foo(void);
 }
 class base2 {
  virtual void foo(void);
 }
 class derived : public base1, public base2 {
  void foo(void);
 }

 void derived::foo(void)
 {
  inherited::foo(); // which foo() do I call?
 }

I understand that if you change the superclass of `derived', then you
have to go through and change all the references to the superclass,
but it leaves you less ambiguous.

In fact, rather than extending the language, just roll your own
`inherited' keyword.  Check out the following saved article:

In comp.lang.c++, on 27 Aug 1993, dag@control.lth.se (Dag Bruck) said:
> I did in fact propose it in the C++ standards committee, but dropped
> the idea when Mike Tiemann (Cygnus Support, father of g++) suggested
> the following sollution:

>  class BaseClass { .... };

>  class D1 : public BaseClass {
>   typedef super BaseClass;
>   // Define super in every class.

>   void f() { super::f(); }
>  };

>  class D2 : public D1 {
>   typedef super D1;
>   // ....
>  };

> You get the same functionality as with a built-in "super" keyword,
> but without extending the language.

--
 Colin Rafferty, Lehman Brothers <craffert@lehman.com>
GCS d++(-) -p+(---) c++(++++) !l u++ e++ m-- s++/- n- h-- f !g w+ t++@ r- y+
 PGP-keyID: C4A60B; fingerprint: 91FED077 BD5588B6 30B372D2 F9172162
     Don't know what pgp is?  Ask me!




Author: jazz@hal.com (Jason Zions)
Date: 08 Feb 1994 17:31:53 GMT
Raw View
In article <1994Feb5.000546.2964@sat.mot.com> hall_j@sat.mot.com (Joseph Hall) writes:

   Paul brings up a good point here.  The deficiency of C++ in this
   area is that there is no syntax that allows you to access
   overridden/inherited members without using class names.  Symantec's
   support for the "inherited" keyword is IMHO a Good Thing and I
   am hoping that something like this will eventually find its way
   into the standard.

   E.g.:

   base::foo()
   {
       // do something
   }

   derived::foo()
   {
       // do something
       inherited::foo(); // call base::foo(), or whatever foo()
    // this class inherited
   }

But whoever developed the "derived" class knows darn well it was derived
from base; when providing an implementation of the derived::foo() method
there's no lack of information as to precisely which class it was derived
from.

Besides, in the context of multiple inheritence, which base class would
"inherited" resolve to?

In short - reserving "inherited" as a keyword is a bad idea, and it buys you
nothing.

Jason Zions




Author: kanze@us-es.sel.de (James Kanze)
Date: 08 Feb 1994 20:06:06 GMT
Raw View
In article <1994Feb5.000546.2964@sat.mot.com> hall_j@sat.mot.com
(Joseph Hall) writes:

|> Seems it was grumpy@cbnewse.cb.att.com (Paul J Lucas) who said:
|> >From article <760204155snz@mel-comm.demon.co.uk>, by gp@mel-comm.demon.co.uk (Guy Pickering):

|> >> When I have a virtual member, the derived version replaces
|> >> the base version. It would be nice if there are a way of
|> >> 'stacking up' virtual members so that the base version is
|> >> called _as well as_ the derived version [...]
|> > Yes: have the derived member call the base one.  You have a
|> > choice as to whether it's pre-called or post-called, hence the
|> > driving is left to you (as it should be).  With ctors/dtors,
|> > there is only one order that makes sense and it's *required*
|> > that they be called; hence the auto-call.

|> Paul brings up a good point here.  The deficiency of C++ in this
|> area is that there is no syntax that allows you to access
|> overridden/inherited members without using class names.  Symantec's
|> support for the "inherited" keyword is IMHO a Good Thing and I
|> am hoping that something like this will eventually find its way
|> into the standard.

|> E.g.:

|> base::foo()
|> {
|>     // do something
|> }

|> derived::foo()
|> {
|>     // do something
|>     inherited::foo(); // call base::foo(), or whatever foo()
|>                       // this class inherited
|> }

This has been discussed and rejected.  The main reason for rejection
is that it is so simple to simulate:

 class B
 {
     //  ...
 } ;

 class D : public B
 {
     typedef B inherited ;
 } ;
--
James Kanze                             email: kanze@us-es.sel.de
GABI Software, Sarl., 8 rue du Faisan, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                   -- Beratung in industrieller Datenverarbeitung




Author: pete@borland.com (Pete Becker)
Date: Mon, 14 Feb 1994 17:57:07 GMT
Raw View
In article <9404515.10674@mulga.cs.mu.oz.au>,
Fergus Henderson <fjh@munta.cs.mu.OZ.AU> wrote:
>
>Huh?  A keyword "inherited" WILL work with multiple inheritence.
>

 Yes. What I had missed in this discussion is that a keyword "inherited"
means "not mine", not "from this base".
 -- Pete




Author: imp@boulder.parcplace.com (Warner Losh)
Date: Mon, 14 Feb 1994 21:23:52 GMT
Raw View
In article <1994Feb11.031258.364@sat.mot.com> hall_j@sat.mot.com
(Joseph Hall) writes:
>inherited:: works perfectly well almost all of the time, and the
>remaining imperfect cases are easily diagnosed.

There is precident for it as well in the language.  Look at overloaded
functions with default parameters (or even without):

 int foo(void *);
 int foo(int);

 foo(0);

is ambiguous, yet this doesn't make overloaded functions any less
useful.

Warner

--
Warner Losh  imp@boulder.parcplace.COM ParcPlace Boulder
I've almost finished my brute force solution to subtlety.




Author: kanze@us-es.sel.de (James Kanze)
Date: 17 Feb 1994 20:05:46 GMT
Raw View
In article <DAG.94Feb13115456@bellman.control.lth.se>
dag@control.lth.se (Dag Bruck) writes:

|> >>>>> On 12 Feb 1994 15:48:13, bobkf@news.delphi.com (BOBKF@DELPHI.COM) said:

|> >In article <27668@alice.att.com> bs@alice.att.com (Bjarne Stroustrup) writes:
|> >|I strongly feel that compiler purveyers should refrain from providing
|> >|``minor features and conveniences'' that has not been approved by the
|> >|committee, and that they should especially refrain from providing
|> >|features explicitly rejected.

|> > It is laughable to take the
|> > position that vendors should implement strictly "pure" C++ when no such
|> > animal exists.

|> Well, you can at least ask vendors not to implement features that the
|> committee has considered and rejected, for example, keyword
|> "inherited."  It has apparently to be repeated.

I know what Dag is getting at, but I'm not sure that I agree.

There are many reasons why the committee might want to reject an
extention.  One of them, for example, might be a total lack of prior
art.  And at present, I would say that there just isn't enough time
left would be very valid.

I don't think that this means that no one should implement these
extensions.  I do think, however, that anyone thinking of implementing
an extension that has been discussed in the committee should at least
try and find out what went on in the discussion, and why the committee
rejected the proposal.  (In the case of the inherited keyword, for
example, there were specific reasons.)  I also think anyone
considering implementing an extension should have a compiler option to
turn it off, for people (like myself) for whom portability *is*
important.

--
James Kanze                             email: kanze@us-es.sel.de
GABI Software, Sarl., 8 rue du Faisan, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                   -- Beratung in industrieller Datenverarbeitung