Article View: comp.std.c++
Article #1150Re: Must derived class reserve space for an empty base class?
From: Jim Adcock
Date: Thu, 24 Dec 1992 00:36
Date: Thu, 24 Dec 1992 00:36
81 lines
4757 bytes
4757 bytes
In article <5450@holden.lulea.trab.se> jbn@lulea.trab.se (Johan Bengtsson) writes: |Jim Adcock (jimad@microsoft.com) wrote: |: In article <5386@holden.lulea.trab.se> jbn@lulea.trab.se (Johan Bengtsson) writes: |: |That two non-generic pointers of the same type (possibly converted from |: |pointer-to-derived) to different objects or data members should be |: |guaranteed to compare unequal. | |Your example (below) shows that at least we have established what we |are disagreeing on. No, it merely establishes one thing that we are disagreeing on. |But the cases where "unnecessary" padding would be required would |have very minor impact on the majority of programs, at least if I |may consider the current implementation of virtuals (vtbl). After all, |inheriting from a truly empty base class (no virtuals) is quite uncommon, |don't you think? No. Since the use of vtables and vtptrs is an implementation decision, not a language decision, classes are "empty" if they have no member objects, regardless of whether or not these classes include pure virtual functions. There is no requirement that implementatins put vtptrs where you are assuming they go. There is no requirement that implementations even *have* vtptrs. Given that the vtptr issue is an implementation decision, I'd say on the contrary "empty" base classes are quite common. As in pure virtual base classes. |If pointer distinctness (as defined above) allows useful semantic constructs, |such as the very common idiom for operator=: |"if ( &other == this ) return", then a small and rare storage overhead |in examples such as the one below could easily be tolerated (IMHO). Other people on the net have complained loudly, repeatedly, and correctly [IMHO] about implementations that consume space when inheriting from a pure virtual base classes. |: If you want object addresses to be |: unique, then write your code so that they are unique. | |You cannot always guarantee that. Suppose you create a class template |that uses pointers to an unknown class (T*) for identity tests (the |template could be specified to handle only statically allocated objects, |if you like). That template cannot know that the type parameter (T) |specifies a class that will have distinct pointers to all instances, |_unless_ pointer distinctness is universally guaranteed. Again you are trying to insist that your template class works for every and all target types which is pure and simple nonsense. Templates can and will always only work on target types that implement not only the right syntax, but also the right semantics. THE ONLY WAY a template can know that the target type supports the right semantics is for the template writer to SPECIFY the semantics, and for the template invoker to CORRECTLY match such. Otherwise all bets are off, even if the syntax happens to match and the template compiles without compile-time error. Again, this is nothing new, and has nothing to do with pointers. If the template writer expects certain correspondences between pointers and object identities, the template writer should specify such, and the template invoker must correctly implement such for the target type. Again, this is nothing new. |There are existing commercial class templates that rely on pointer |distinctness. Are they invalid? Of course they're "valid" -- they're simply not strictly portable. They meet the needs of a portion of the marketplace, and do not meet the needs of others. If they want to meet the needs of a greater portion of the marketplace, then they need to write their classes to rely on even fewer implementation dependences. In practice "portability" is never an absolute, its only a relative term. In practice, no interesting program or library is "strictly portable". Interesting programs or libraries only have sections of code that can be informally referred to as "portable" and other sections of code that are clearly not strictly portable. By making things more portable the implementor makes porting the code less expensive, while typically raising BOTH the cost of implementing that code AND the cost of executing that code. While we tend, as a rule of thumb, think of more portable code as being better, in reality such comparisons are only relatively true.
Technical Details
Message-ID:
<1992Dec24.003604.701@microsoft.com>Path:
arc1-ca.pugleaf.net!sparky!uunet!microsoft!hexnut!jimadReferences:
<1992Dec16.202800.3398@microsoft.com> <5450@holden.lulea.trab.se>Show Full Headers
Complete Article Headers
Newsgroups: comp.std.c++ Path: arc1-ca.pugleaf.net!sparky!uunet!microsoft!hexnut!jimad From: jimad@microsoft.com (Jim Adcock) Subject: Re: Must derived class reserve space for an empty base class? Message-ID: <1992Dec24.003604.701@microsoft.com> Date: 24 Dec 92 00:36:04 GMT Organization: Microsoft Corporation References: <1992Dec16.202800.3398@microsoft.com> <5450@holden.lulea.trab.se> Lines: 81