Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!zaphod.mps.ohio-state.edu!sol.ctr.columbia.edu!emory!att!hriso!attdso!westmark!mole-end!mat From: mat@mole-end.UUCP (Mark A Terribile) Newsgroups: comp.lang.c++ Subject: Re: Byte padding question Summary: C abhors a vacuum Message-ID: <440@mole-end.UUCP> Date: 12 Sep 90 03:38:08 GMT References: Distribution: comp Organization: mole-end--private system. admin: mole-end!newtnews Lines: 70 > When building a class hierarchy in C++ we found that some extraneous > char's were being inserted into the C structure produced by the AT&T front > end. After writing a fairly large test program it was found that these bytes > were only being generated ... when an empty class (methods only, no member > variables) was the base class. I also noticed that in it's child class the > extra byte generated for the empty base class was added as well as a new char > array of size 1. > In the work our department is doing, this will cause problems in > the future and we would like to clear up the reason why this is > happening (and even better how to stop it happening!). As to why the empty char is being inserted into the empty base class-- the underlying C implementation can't handle an empty struct; there must be a member, so the smallest possible datum is used. The array in the derived class is *probably* there to force subsequent data members back to the ``correct'' or machine optimal alignment. After a non-array char member, the next member can be begun at an odd boundary if the machine will support it. On some machines, this will be costly; on others it will leave a hole that C++ may have a hard time dealing with when computing member addresses (although THAT is speculation on my part). You are probably stuck with it. You might try (I haven't got a recent cfront handy so this is pure speculation) making the base class abstract (put a pure virtual function in it); cfront *might* be smart enough to know that it won't have to create the base class object as a complete object. But I wouldn't bet on it. You might take your added data for the derived class and stuff it all into a struct from which which you can multiply and publicly derive the derived class; that way you will at least have a well-defined data layout for those data and you can convert the derived class to it at will. class Base_with_funcs { . . . your member functions for this hierarchy . . . }; struct Data_for_Derived_1 { . . . all the member data needed for Derived_1 . . . }; class Derived_1 : public Base_with_funcs, Data_for_Derived_1 { . . . the member functions for Derived_1, . . . . . . which will have the Data_for_Derived_1 . . . . . . member data in their class name space . . . }; . . . // For the sake of argument ... ostream& operator<< ( ostream&, const Base_with_funcs& ); ostream& operator<< ( ostream&, const Data_for_Derived_1& ); Derived_1 d1( . . . ); cout << (Data_for_Derived_1&) d1; I don't know when cast to a reference type slipped into C++, (or whether it was there all along) but it's real nice to have. -- (This man's opinions are his own.) From mole-end Mark Terribile