From: tmb@arolla.idiap.ch (Thomas M. Breuel)
Newsgroups: comp.lang.c++
Subject: Re: zero-length datatype
Date: 10 Sep 92 16:32:01 GMT
Reply-To: tmb@idiap.ch
Distribution: comp
Organization: IDIAP (Institut Dalle Molle d'Intelligence Artificielle
	Perceptive)
In-reply-to: jss@lucid.com's message of 10 Sep 92 00:37:26 GMT

In article <1992Sep10.003726.27140@lucid.com> jss@lucid.com (Jerry Schwarz) writes:

   In article <TMB.92Sep7171355@arolla.idiap.ch>, tmb@arolla.idiap.ch (Thomas M. Breuel) writes:
   |> C++ seems to be lacking in a data type that is guaranteed to be zero
   |> length.


   This understates the situation.  C++ guarantees that no object
   will have size 0.

I pointed this out myself in my posting.

   For example 

	   struct Z { } ;

   may not have size 0.

   One reason for this constraint is to ensure that no two objects
   have the same address.  In particular the elements of an array
   are always at different addresses.

	   Z a[10] ;

   Without that constrain a[0],...,a[10] would all compare equal.

I think what you meant to say is that "without that constraint,
a+0,...,a+10 would all compare equal", since even with that
constraint, a[0],...,a[10] should all compare equal (if you define
operator==), since they have the same value.

And, my answer is, so what? The usual identities for arithmetic
would still be preserved. There is nothing intrinsically bad
about "sizeof (Z) == 0".

In any case, I am not suggesting that the semantics of empty
structures be changed in any way, but that a new type (which could
coincide with "void" but need not) of zero length be introduced.  No
existing code would be affected by my suggestion, since currently no
code defines or uses such zero-length objects.

   The constraint predates templates. Maybe it should be reconsidered.
   However that would require some consideration of the effect 
   on existing code, and on common programming idioms.

   For example something like

	   Z a[10] ;
	   ... 
	   count = sizeof(a)/sizeof(Z)

   suddenly becomes a divde by zero.

Well, "void" would pretty much only be used as an argument to a
template. And, yes, no question about it, unsuspecting template code
could behave in odd ways when given the zero-length type as an
argument (this particular case happens to be statically detectable)
(*).  But unsuspecting template code can also behave in odd ways or
even fail to type check when given some other type as an argument that
doesn't have quite the types or semantics that the template code
expects. That's an intrinsic limitation of the C++ template system and
unrelated to the existence of zero-length datatype.

There are, in fact, two issues: (1) should a zero-length datatype be
introduced, and (2) could "void" be used to denote it.

I definitely believe in (1). I don't know whether (2) can be achieved
without some snag, but "void" would be the logical notation for a zero-
length datatype, and it might remove many of the seemingly arbitrary
restrictions on what you can and cannot do with "void".

					Thomas.

(*) Two examples:

The following terminates immediately, which is probably good:

	void a[10];
	for(void *p = a;p<a+10;p++) ... 

The following never terminates, which is probably not so good:

	void a[10];
	void *p = a+10;
	while(--p>=a) ...

Template code that uses descending loops with pointers over an array
of a template argument would simply not work if that template argument
is "void". That's no different from lots of other failures that can
occur with templates. The following loop, for example, may never
terminate if the range of type T is too small (e.g., T is "char"):

	template <class T>
	... for(T x=0;x<1000;x++) ...

Similar problems occur if you use a floating point type instead of an
integral type, or, in fact, if you use any type as a template argument
that doesn't have quite the right semantics for the template class.
Newsgroups: comp.lang.c++