Path: utzoo!utgpu!water!watmath!clyde!att!pacbell!ames!ll-xn!mit-eddie!uw-beaver!uw-june!uw-entropy!dataio!pilchuck!ssc!happym!polari!rlb From: rlb@polari.UUCP (rlb) Newsgroups: comp.lang.c++ Subject: Re: classes with no data members Summary: Empty classes revisited for the last time (by me, anyway) Keywords: sizeof,empty classes,new Message-ID: <475@polari.UUCP> Date: 21 Jun 88 00:50:43 GMT References: <464@polari.UUCP> <7943@alice.UUCP> <470@polari.UUCP> <10399@sol.ARPA> <4614@haddock.ISC.COM> Organization: Polarserv, Seattle WA Lines: 71 }Prologue: I believe I'll have one last whack at the minor, but interesting case of "empty classes". A note of interest: dpANS rationale refers to "the general principle of not providing for 0-length objects". Hmmmm.... }Discussion: In article <4614@haddock.ISC.COM>, karl@haddock.ISC.COM (Karl Heuer) writes: > Assume the existence of a C++ compiler that allows zero-sized objects (ZSOs), > i.e. one that does not insert a shim in an empty class. > > Several people have stated the opinion that any two object pointers should be > distinguishable, and that calling `new empty' twice should yield unequal > (hence non-NULL) values. I'm not convinced. I am. > > Given `int a[N]', &a[N] is a valid pointer that doesn't point anywhere. That > is, it's guaranteed that &a[N] can be stored in a pointer variable, but > dereferencing it is undefined. And it's not guaranteed to be distinct from > other pointers: &a[N] may well be equal to &b[0]. I think ZSO pointers are in > the same category. (After all, it's just the limiting case N=0.) The Walking Lint stumbles a bit here :-). It certainly is guaranteed to be distinct from a possibly quite large number of other pointers -- those that point to a[0] through a[N-1]. It is true that a pointer to &a[N] cannot be dereferenced legally and you may personally choose to define that as "doesn't point anywhere" but: A) that definition does not remove the restrictions on the pointer (must play well with other pointers into the same object :-), and B) this is all just an analogy (not quite a correct one, I think) for the subject under discussion, therefore we proceed... > > Also, consider `empty x[2]'. Surely &x[0] and &x[1] must compare equal? If > so, why should the situation be different if I declare `empty x0, x1'? Or if > I call `new empty' twice? I assume your posting is based on the feeling (which I also have) that it is pretty damn hard to come up with a realistic example in which it *matters* whether or not two pointers to different objects of the same empty class are distinguishable. It is much easier to note that it could be "surprising" that two separately declared objects have addresses which compare equal. To use your own example, &x[0] and &x[1] definitely must NOT compare equal, because the expression "&x[1] - &x[0]" must evaluate to the integer "1". Else you must clutter the language definition up with a great many "except for zero-sized objects". > > Btw, in ANSI C, malloc(0) either gives you a ZSO or a NULL pointer. In C++, > new(0) apparently hasn't been well-defined. (This is a serious flaw, in view > of the legality of user-defined new. The language definition should either > specify the behavior, or explicitly state that it's undefined.) Can't argue that it's a flaw, but I also can't really call it serious because then what stronger word would I be able to use for the fact that several areas of the syntax of the grammar (e.g. "new" with initializers, class member initializers, etc.) itself are entirely up in the air? Catastrophic? This is, of course, deliberate rabble-rousing; the non-alarmist view is that Language Definition == (AT&T implementation + Reverse Engineering) I've watched enough episodes of Green Acres to know that when everyone around you is using logic like this, ya better just go along with it:-). > > Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint A couple of postings have appeared to the effect "Machine architecture X plus clever trick Y allows me to create a separate address space for pointers to zero-sized objects." This is at least theoretically interesting: such an arrangement seems to allow a C++ implementation where empty objects consume no space (but only if "new" were well-defined and defined in favor of this). In practice, it don't seem likely that any implementor would ever go to the trouble. }Epilogue: I conclude that "empty classes" are nasty little beasts that are not worth the minor convenience of having the compiler create the virtually- always-in-practice-needed dummy member on the programmer's behalf. C seems quite sensible to eschew zero-sized objects. While "The C++ Programming Language" does not seem to be a bad language definition, it's given me a lot of respect for just how good a job K&R did on their first edition.