From: shang@corp.mot.com (David (Lujun) Shang)
Subject: Re: zero-length datatype
Reply-To: shang@corp.mot.com
Organization: Motorola, Inc., Software Research and Development, Rolling Meadows, IL. 60008
Distribution: comp
Date: Thu, 10 Sep 92 18:18:36 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.  For example 
> 
> 	struct Z { } ;
> 
> may not have size 0.
>

Note that C g++ implements empty struct or class with size of zero. 
g++ also allows an array with zero number of member with size of zero.

Zero size object is useful sometimes. For example:

struct Empty {};

class Chain
{  TextChain * next;
   TextChain * prev;
   int node_size;
   Empty chain_node;  // or  char chain_node[0];
  public:
   // operations on chain and chain node
};

chain_node only provides the start address of the chain node. With
size zero, it does not occupy any space. It would be awkward that 
the field chain_node occupies an additional byte while it is useless
and represents the wrong start address of the actual chain node. This
technique is commonly used when templete is not available and you
don't like to sprit memory into small pieces through many pointers.
Even with template, you can still use this techique to avoid large
static code expansion by presenting only a template interface which
is actually impelemented at low level.
 
> 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.
>

This is an implementation issue. The language itself has nothing to 
do with a particular address protocol. An empty object needs no 
storage to store its state, so we need not to take care of its 
address, it can be anything by logic, i.e. to read and write through 
an empty object address (pointer or reference) is logically equivalent 
to null operation, and to compare two empty object addresses is 
meaningless.

The implementation can assume the address of an empty object is where 
it is defined so that its address may be used in some particular way 
as I mentioned in the above example. But again, it is an implementation 
issue.

> 	Z a[10] ;
> 
> Without that constrain a[0],...,a[10] would all compare equal.
> (I know a[10] isn't a real member, but ANSI C guarantees that
> it is legal to take its address).
> 

I don't see any reason why we should compare two empty objects. 
An empty object has no state. It is meaningless to compare objects 
without states. The result of the comparison is indeterminate. Of 
cause the implementation can assume that the result of comparison 
is always equal.

> Another is that  new Z will never return the same adddress.
> Of course you could add this as an additional constraint on
> operator new if you wanted to.
> 

It doesn't matter what the address the new operator returns for an 
empty object. As I said already, the address for an empty object is 
meaningless.

> The constraint predates templates. Maybe it should be reconsidered.

Yes. I don't see zero-size objects would violate anything.

David Shang

Newsgroups: comp.lang.c++