From: rwk@silver.sbi.com (Richard W. Kreutzer Consultant)
Newsgroups: comp.std.c++
Subject: Object in this mirror may appear smaller than they are
Date: 7 Oct 92 22:15:45 GMT
Distribution: comp
Organization: Integra Software Corporation

How many of you using cfront or gcc, use a base class with no instance
variables (i.e. no non-static member variables)?  Did you realize the derived
objects may be as much as 4 bytes larger than you might have thought.  (I have
not tried any other C++ compiler, but would be interested to know if there are
any which avoid the problem.)

Page 164 of the ARM states:

	"Objects of an empty class have nonzero size."

It goes on to give the following example of an empty class:

	class Empty {};  // class with no members

Is this class empty?

	class foo {void bar();}

Both cfront 2.1 and gcc 2.2.2 say it has size 1.

This is not the real problem - assuming "class foo" above is indeed empty, by
definition, can someone please explain to me the rational for requiring an
"empty" class to be of size > 0?  The only statement in the ARM (p. 164) about
it is that "Empty classes can be used as place holders during development".
This does not seem (IMHO) to be a significant justification, since it would be
trivial for a programmer to add a 1 char member variable if he really wanted
to ensure that:

	{
	Empty e1, e2;
	assert(&e1 != &e2);
	}

was true.

I am suspicious that the real reason was that certain C compilers used by
cfront would not allow empty struct declarations and this was an easy way to
get around it. (BTW: What does ANSI C say on the subject?)  Gcc (in ANSI C
mode or otherwise) allows a struct to be of size zero.  I have not heard any
complaints about this.  With gcc in the above example, e1 and e2 are at the
same location (which is fine with me).

The problem with non-zero empty class sizes is: compiler developers find it
convenient to sneak in a hidden non-static variable thereby ensuring objects
of non-zero size.  When this "empty class" is a base class, the derived class
inherits the hidden variable from the base class, increasing the size of the
derived class.  Depending on structure alignment constraints, this can as much
as double the size of the derived class.

Here is an example:

	#include "iostream.h"

	class Base {
	  // a bunch of function definitions - irrelevant to the problem
	  };
	
	class Derived : public Base {
	  int a;
	  // more irrelevant functions
	  };
	
	main() {
	  cout << sizeof(Derived) << endl;
	  }
	
On a Sparcstation, this prints sizeof(Derived) as 8 when it would appear that
it would be 4 (the size of "int a").

Certainly there are MANY applications which cannot afford 8 bytes per object
when only 4 are needed.  Why make it difficult for compiler developers to
implement C++?  Why not simply allow "empty" classes to be size zero?


P.S.

I cross posted something similar on comp.lang.c++.  Sorry if this is redundant,
but I wanted to see what you "standards" folks had to say.
--

--
        Richard W. (Dick) Kreutzer
Net:    rwk@quark.sbi.com				CIS:	70702,2174
Voice:  +1(801)571-2446					FAX:	+1(801)571-2448
Mail:   Integra Software Corp.; 1378 Jasmine Avenue; Sandy, UT 84092 (USA)
Newsgroups: comp.std.c++