dove@rocket.stars.flab.Fujitsu.JUNET (Webster Dove) (02/14/89)
I have recently had two staff waste a day each chasing very similar problems with virtual members. I believe a minor change to the language definition could eliminate a significant pitfall that now exists. Both people were working on Interviews applications. Mike was trying to upgrade an old application to a new Interviews rev. Kevin was writing a new application. Part of the both applications required that the programmer create a virtual function member in a class they wrote that would catch an event (exposure I believe). Unfortunately, in Mike's case, the syntax of the call had changed between revs and in Kevin's case, the documented syntax was wrong. The result was that the function members they had declared were considered new members (as opposed to shadowing virtuals from the base class) and were never called because their syntax was not the required one. Since C++ requires that the base class provide a default member, the package has one which does nothing. Therefore, the programs compiled without any warnings. However, when they were run the results were very obscure behaviors that took considerable skill and effort to diagnose. My recommendation is the following: eliminate the requirement to restate the syntax of virtual functions in the derived class declaration. If they must be restated, require the keyword "shadow" in front to explicitly connote that the declaration must "hook up" with an identical virtual declaration in the base class. This would have given my two staff obvious syntax errors to correct and reduced the expended time by orders of magnitude. I must emphasize that these were both competent people who independently ran into the same problem. It suggests to me a substantial risk in using the language. -- Dr. Webster Dove Computing Systems and Architectures Advanced Signal Processing Engineering (ASPEN) Dept. Sanders Associates (a Lockheed Company)
ark@alice.UUCP (Andrew Koenig) (02/15/89)
In article <DOVE.89Feb14122134@rocket.stars.flab.Fujitsu.JUNET>, dove@rocket.stars.flab.Fujitsu.JUNET (Webster Dove) writes: > My recommendation is the following: eliminate the requirement to > restate the syntax of virtual functions in the derived class > declaration. If they must be restated, require the keyword "shadow" > in front to explicitly connote that the declaration must "hook up" > with an identical virtual declaration in the base class. This would > have given my two staff obvious syntax errors to correct and reduced > the expended time by orders of magnitude. Here's a much easier solution: Issue a warning when a non-virtual function declaration hides a virtual function with the same name declared in a base class. Adding a new keyword is not a minor change. -- --Andrew Koenig ark@europa.att.com
joemac@Apple.COM (Joe MacDougald) (02/16/89)
There has been a proposal here at Apple to extend the language to cover this unsafe situation. The keyword suggested to be required when a virtual function was specialized in a derived class is "overload". This keyword is required in Object Pascal in the analogous situation. For portability one could simply "#define overload virtual". This was suggested to Bjarne but alas the language is too mature for such an addition. | UUCP ...!{decwrl, inhp4, hplabs, sun}!apple!joemac | | Domain joemac@apple.com | | AppleLink MACDOUGALD1 | | "be the ball ..." |
johnson@p.cs.uiuc.edu (02/18/89)
Webster Dove described the problem that can occur when the implementer of a derived class declares a virtual member function with the wrong name. Briefly, the compiler does not issue any warnings but uses the function inherited from the base class, and the new function never gets called. One way to minimize this problem is to make base classes abstract (i.e. their virtual functions are only place-holders) and to make the virtual functions give error messages if they are ever called. This technique has worked well for us. Ralph Johnson
rfg@riunite.ACA.MCC.COM (Ron Guilmette) (02/19/89)
In article <DOVE.89Feb14122134@rocket.stars.flab.Fujitsu.JUNET> dove@rocket.stars.flab.Fujitsu.JUNET (Webster Dove) writes: >I have recently had two staff waste a day each chasing very similar >problems with virtual members. <<... a sad story ensues ... >> >...Since C++ requires that the base class provide a default [virtual] member, >the package has one which does *nothing*. Therefore, the programs >compiled without any warnings. However, when they were run the >results were very obscure behaviors that took considerable skill and >effort to diagnose. Please correct me if I am wrong, but couldn't you have avoided your trouble if you had defined the "default" virtual member function in the base class to do something which would let you know that it had been called by mistake, e.g. calling abort() or something? That is what I do when I have virtual member function declared in a base class which are just there as "placeholders" are which are not supposed to be called in practice. -- // Ron Guilmette - MCC - Experimental (parallel) Systems Kit Project // 3500 West Balcones Center Drive, Austin, TX 78759 - (512)338-3740 // ARPA: rfg@mcc.com // UUCP: {rutgers,uunet,gatech,ames,pyramid}!cs.utexas.edu!pp!rfg
dove@rocket.stars.flab.Fujitsu.JUNET (Webster Dove) (02/23/89)
In article <91@riunite.ACA.MCC.COM> rfg@riunite.ACA.MCC.COM (Ron Guilmette) writes:
Please correct me if I am wrong, but couldn't you have avoided your
trouble if you had defined the "default" virtual member function in
the base class to do something which would let you know that it had
been called by mistake, e.g. calling abort() or something?
Yes. Exactly my advice when we write the base class (also recommended
by johnson@p.cs.uiuc.edu). However, in this case, the base was
written by Mark Linton and at least at the time he did not recognize
the risk.
That is what I do when I have virtual member function declared in a
base class which are just there as "placeholders" are which are not
supposed to be called in practice.
That will detect at run time a failure to overload the base virtual
definition. I guess barring a change to the language, I would prefer
a compiler warning of the form recommended by Andrew Koenig:
Issue a warning when a non-virtual function declaration
hides a virtual function with the same name declared in
a base class.
This would detect the problem at compile time, and could be added to a
compiler as a switch (as the -fsingle switch was added to correct the
single to double conversion misfeature in C).
--
Dr. Webster Dove
Computing Systems and Architectures
Advanced Signal Processing Engineering (ASPEN) Dept.
Sanders Associates (a Lockheed Company)
mikem@otc.otca.oz (Mike Mowbray) (02/26/89)
** Ron Guilmette suggested that the trouble could be avoided by having
the base class version of the virtual function do something like abort().
** Webster Dove supported this, indicating that this was his standard
advice when writing a base class.
If the inheritance depth were greater than 1, this scheme wouldn't make sense.
Mike Mowbray ACSnet: mikem@otc.oz
Network R&D UUCP: {uunet,mcvax}!otc.oz!mikem
|||| OTC || Phone: (02) 287-4104
Snail: GPO Box 7000, Sydney, Australia