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.