dove@batman.uucp (Webster &) (06/02/90)
The problem: Suppose a user of a library (e.g. InterViews) has set up many virtual member functions for derived classes that inherit class declarations from the library. Assume that these member functions are being invoked somewhere inside the library that the user is aware of in general, but not in detail. Now assume that a new release of the library comes out and the details of the calling syntax for some of these virtual functions is superficially changed, and the user has not read all the new documentation carefully or the documentation fails to mention the change. This causes the derived class virtual functions to "fail to link" with the base class declarations leading to program failure. There is no compile time warning since the derived virtual declarations are now treated as new function members starting at the derived class level. I have had this happen several times on programs I controlled. I see this as a severe risk. Is this being fixed? I have previously (5/12/87) discussed this issue and I gather it has come up as a recurring theme. I think I have a fix. Since I have not been reading this list for a while, forgive me if it has been discussed. Suppose you allow the derived class to inherit the declaration of the virtual member. class base_class { public: virtual base_virtual(); }; int base_class::base_virtual() { ... default behavior ... } class derived_class : public base_class { } int derived_class::base_virtual() { ... derived behavior ... } This would be back compatible with existing code, not require any new keywords, and allow me to fix my problem with a library line InterViews without requiring any changes to the library. This allows me to explicitly state (by ommision) that I am expecting there to be a matching inherited virtual and would yield a compile time error if that linkage failed. Comments? Web -- Dr. Webster Dove Dr. Webster Dove Experimental Computing Systems ('X') Lockheed Sanders Inc. Signal Processing Center of Technology 144 Daniel Webster Hwy. Lockheed Sanders Inc. Merrimack, NH. 03054 email: .!uunet!rocket!dove (or ) @uunet.uu.net:dove@rocket.uucp
jef@well.sf.ca.us (Jef Poskanzer) (06/03/90)
In the referenced message, dove@batman.uucp (Webster &) wrote: >Suppose you allow the derived class to inherit the declaration of the >virtual member. > >class base_class { >public: > virtual base_virtual(); >}; > >int base_class::base_virtual() { ... default behavior ... } > >class derived_class : public base_class { >} > >int derived_class::base_virtual() { ... derived behavior ... } > >This would be back compatible with existing code, not require any new >keywords, and allow me to fix my problem with a library line >InterViews without requiring any changes to the library. This allows >me to explicitly state (by ommision) that I am expecting there to be a >matching inherited virtual and would yield a compile time error if >that linkage failed. I agree that this is a big problem with C++, but your proposed solution seems weird. Explicitly state by omission? What does the derived class do if it doesn't want to re-define the function? Or if it wants to define a totally different function that happens to have the same name? How about if the derived class can declare that it will be re-defining a virtual function without having to re-state the type and arguments of the function? Like this: class derived_class : public base_class { base_virtual; } Hmm, except this doesn't work either if the base class defines more than one virtual function with that name, but with different arguments. I dunno, I just started on C++ a few weeks ago, and already I love/hate it. --- Jef Jef Poskanzer jef@well.sf.ca.us {ucbvax, apple, hplabs}!well!jef "She's not a woman -- she's the Terminator!"
roger@procase.UUCP (Roger H. Scott) (06/03/90)
In article <DOVE.90Jun2102921@batman.uucp> dove@batman.uucp (Webster &) writes: >The problem: (paraphrased somewat -rhs) > >Suppose a user of a library (e.g. InterViews) has redefined many virtual >functions from the library. Now assume that a new release of the >library comes out and the type signature for some of these functions is changed, > and the user is not fully aware of the change. > >This causes the derived class virtual functions to "fail to link" with >the base class declarations leading to program failure. There is no >compile time warning since the derived virtual declarations are now >treated as new function members starting at the derived class level. 1. This is not a language definition issue, requiring a language change. It is a compiler design issue, requiring a compiler change. 2. The relevant change has been made in the AT&T's 2.0 cfront compiler. In the case you describe you would get a warning that the base class's virtual function(s) have been hidden by the functions in the derived class. Remember that overloading only occurs within a single scope, and the members of a derived class are considered to be in a different scope than the members of a base class. >... >Suppose you allow the derived class to inherit the declaration of the >virtual member. Think about overloading and you will see that things are not nearly as neat and simple as you describe them. @ @ @ @ @ @ @ @ @
jamiller@hpcupt1.HP.COM (Jim Miller) (06/07/90)
>I agree that this is a big problem with C++, but your proposed solution >seems weird. Explicitly state by omission? What does the derived class >do if it doesn't want to re-define the function? Or if it wants to >define a totally different function that happens to have the same name? > >How about if the derived class can declare that it will be re-defining a >virtual function without having to re-state the type and arguments of >the function? Like this: > >class derived_class : public base_class { > base_virtual; >} > > Jef Poskanzer jef@well.sf.ca.us {ucbvax, apple, hplabs}!well!jef > "She's not a woman -- she's the Terminator!" > As noted, overloading would give problems if you do not give the type of arguments. It seems to me that I want to redefine a routine I should give the same parameters, but the compiler should help me make sure that the base virtual function has not changed it's parameters. I want to introduce a new keyword (oh, no, not another!): "virtual+". Virtual+ says that it is replacing a virtual function from an inherited class. If there is no match, the compiler gives and error. "virtual-" might be also introduced, meaning this function is NOT supposed to replace a base function (at least it didn't when I wrote it...). class base_class { public: virtual base_virtual(); }; int base_class::base_virtual() { ... default behavior ... } class derived_class : public base_class { virtual+ base_virtual(); // name and parms must match exactly! ^**** } int derived_class::base_virtual() { ... derived behavior ... } I think this would solve the "but the library changed and never told me" problem. It should be completely compatible with existing code. I would think that I would have to know EXACTLY the parameters of the routine I'm trying to replace in my new function. Yes, there would be still gotcha's. If you are counting on type conversion, then the base class includes a new function by the same name that now has the right types. In that case your derived function would not get called after type conversion, the new function would get called without any type conversion. However, by doing explicit type conversion you could write your code so that it would call the correct routine no matter what the base class did. This mechanism would allow one to program more defensively than is now possible. jim - $.02 - miller These opinions are not necessarily those of the company I work for.