Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!hplabs!hp-pcd!hplsla!jima From: jima@hplsla.HP.COM (Jim Adcock) Newsgroups: comp.lang.c++ Subject: Re: address of virtual function (revisited) Message-ID: <6590118@hplsla.HP.COM> Date: 9 May 89 19:00:30 GMT References: <904@garya.Solbourne.COM> Organization: HP Lake Stevens, WA Lines: 113 > >Again, for OOP to be affordable, these simple, everyday "get" and > >"put" type functionalities must be handled at minimal cost. > >Otherwise programmers will violate strict encapsulation, and come > >up with "hack" solutions. > > I get a frustrated by assertions of this kind. By any standard C++ > is "affordable", especially when compared to languages like Smalltalk > or Objective C. Note that the item I am replying to was sumbmitted > only to comp.lang.c++ so I have to read this as a suggestion that > C++ isn't "affortdable". (I suppose I could also read this as an > argument for my contention that C++ supports non object > oriented styles and therefore derives its affordability by avoiding > OOP when neccessary, but the tenor of the item I'm replying to > doesn't suggest that reading to me. I apologize if I'm misreading > Jim Adcocks note.) Sorry, I meant my comments in the context of the relative cost of virtual functions, compared to simple lookups as you discuss below: > In fact, C++ puts you at a low enough level so that (with out > violating the type discipline) it is possible to program the > operation under discussion (finding the "actual" size of an > object) as a simple lookup. > > class B > public > const size_t size ; > B(int i) : Size(i) ; > } ; > > class D : B { > D(...) : B(sizeof(D)) { ... } > } ; > > B* p ; ... p->size ... ; > > Yes, there is a certain amount of pain involved in programming this > explicitly. But recall that the original complaint was that C++ > doesn't provided an "affordable" enough way to do this operation. Again, the complaint is that virtual functions [as presently implemented in cfront with a pretty good backend C compiler] is too expensive relative to these simple lookups. While there are good optimizing C compilers out there, what they are good at optimizing is not the kind of code cfront produces. If you had a backend C compiler that can infer when to inline functions, or look at constant tables (as in vtables) and not add constants of zero, etc, etc, then you presumably could get some pretty good code when using cfront. Alternately, presumably, some of the kinds of optimizations specific to C++ could be put into cfront, and more general optimizations could be left to back end compilers. Unfortunately, at least when using K&R compilers for the back end, cfront knows a lot more about the code to be produced than the backend compiler. So cfront would be the place that a lot of the optimzations would have to occur. So, for example, right now, with my combination of cfront and back end compiler, Jerry's approach, where you violate the encapsulation of an object, access its instance variables directly, and lock future derived classes into using one approach to returning "size", and force a syntax of p->size rather than p->size() -- then generates code like such: movel a2@,sp@- Where as if one takes the "Object Oriented" approach of using virtual functions to return these values, so that some future class -- a linked list maybe -- can have a virtual function that calculates "p->size()" on the fly, then the [minimum] code that gets generated is: movel a3@(4),a0 addqw #8,a0 addw a0@,a3 movel a3,sp@- movel a0@(4),a0 jbsr a0@ | | V link a6,#0 movel a6@(8),a0 movel a0@,d0 unlk a6 rts | | V movel d0,sp@- So, as I was trying to say before, one can clearly see that attempts to encapsulate an object, accessing its instance variables using virtual functions, in order to allow flexibility in future derived classes, presently costs dearly; rather than just punting, and allowing direct access to some of an objects instance variables. About 10-20X slower. In many [most?] cases, a good optimizing C++ -> assembly compiler, or a good combination of a good optimizing C++ -> C and C -> asm compiler would be able to avoid generating most of this code most of the time. I don't see this is a problem with the language. Its just that C++ compilers need to do a better job of optimizing either the C or assembly code they produce. Its silly to pretend an optimizing C compiler is going to find all the optimizations possible out of the stuff cfront presently produces! While there are times when Jerry's suggestion is the way to go, there are also times when one would like to preserve the flexibility that virtual functions allow, and one would still be able to count on code being produced at minimum cost. The present 10-20X factor is simply too much. BUT: C++ is still much cheaper than Smalltalk and ObjC, even with the present weaknesses in the code produced.