Coda File System

Re: gcc-3.2

From: Nix <nix_at_esperi.demon.co.uk>
Date: 02 Nov 2002 13:49:20 +0000
On Fri, 1 Nov 2002, Jan Harkes stipulated:
> On Fri, Nov 01, 2002 at 12:03:47AM +0000, Nix wrote:
>> On Wed, 30 Oct 2002, Jan Harkes moaned:
>> > Similarily, allocation of persistent objects, it used to be the case
>> > that the range [&foo, &foo+sizeof(foo)] would contain all information
>> > associated with a C++ object. However the newer gcc's store miscelaneous
>> > data outside of that range, often even allocated off the heap so that
[snip]
>> The C++ ABI requires that such things will happen for non-POD types, but
>> not for POD types; so avoid virtual functions, constructors,
>> destructors, and private and protected data and you should be fine.
> 
> Ahhh, that is useful to know. Is this part of the standard in such a way
> that we can rely on this until the C++ standard is revised?

God, no :)

It's the cross-vendor-compatible C++ ABI which is used by many compiler
vendors for IA-64, and which is used by GCC 3 as its C++ ABI on every
platform it can be got to work on (basically, every platform supporting
ELF, and coming very close on others).

It's documented at <http://www.codesourcery.com/cxx-abi/>.


The C Standard requires that, for C, all the data for a struct fit
between the struct's address and sizeof(struct); arrays wouldn't work
without that guarantee; and section 2.2 of the ABI spec states that

,----
| 2.2 POD Data Types
| 
| The size and alignment of C POD types is as specified by the base (C)
| ABI. Type bool has size and alignment 1. All of these types have data
| size and non-virtual size equal to their size. (We ignore tail padding
| for PODs because the Standard does not allow us to use it for anything
| else.)
`----

This can't really ever be broken without breaking C/C++ link-time
compatibility and `extern "C"' into the bargain, which I think I can say
isn't going to happen :)

(It would also break iostreams on all platforms using GNU libio for
iostreams --- that is, all platforms using the GNU libc; that's more
than just Linux and the Hurd nowadays; it's working on FreeBSD again...)

The C++ FAQ lite informally defines POD types at
<http://www.parashift.com/c++-faq-lite/intrinsic-types.html> as

,----
| A type that consists of nothing but Plain Old Data.
| 
| A POD type is a C++ type that has an equialent in C, and that uses the
| same rules as C uses for initialization, copying, layout, and
| addressing.
| [...]
| The actual definition of a POD type is recursive and gets a little
| gnarly. Here's a slightly simplified definition of POD: a POD type's
| non-static data members must be public and can be of any of these types:
| bool, any numeric type including the various char variants, any
| enumeration type, any data-pointer type (that is, any type convertible
| to void*), any pointer-to-function type, or any POD type, including
| arrays of any of these. Note: data-pointers and pointers-to-function are
| okay, but pointers-to-member are not. Also note that references are not
| allowed. In addition, a POD type can't have constructors, virtual
| functions, base classes, or an overloaded assignment operator.
`----

So for such types you're guaranteed to get behaviour Just Like C, and
the C++ Standard and G++ ABI both guarantee this.

> I guess this means that any object stored in RVM (fsobj/volrep/repvol)
> should just have public data and methods. How about inheritance? We have

> a base class 'volent' that contains common functionality of both
> replicated volumes and the underlying volume replica's.

I expect that you'll have particular problems with what the ABI spec
calls `dynamic classes', that being `a class requiring a virtual table
pointer (because it or its bases have one or more virtual member
functions or virtual base classes)'.

The virtual table pointer points to a virtual table; there's fewer of
those than there are instances (see section 2.5.1), so the virtual table
therefore *must* be located outside the instance :)

(A damned good thing too, or your memory consumption would shoot up.)

> I'm not sure whether I can really get away without any constructors or
> overloaded allocators. If we really have to lose those it is probably

I don't know if constructors or overloading will work; such types are
not POD, but I can't see an obvious problem; my quick check for
type-compatibility between a randomly hacked up C struct

struct a_struct
 {
  int a;
  double b;
  const char *c;
  struct
   {
    int e;
   } d;
 };

and the corresponding C++ type with constructor and destructor

struct a_struct
 {
  int a;
  double b;
  const char *c;
  struct
   {
    int e;
   } d;
  a_struct() { (printf) ("hi"); }
  ~a_struct () { (printf) ("bye"); }
 };

indicated no layout differences between the data members of the two
classes. So G++ seems to be conforming to its ABI spec here :)

> better to only access RVM objects through a well defined layer written
> in C.

That'd be sure to work, but I think it might be going further than
necessary. Steer clear of virtual methods and inheritance and, for now,
with GCC, you'll be OK; stick to POD types and you'll always be OK,
regardless of C++ compiler.

>> That's definitely a bug. If you stick a report into GNATS I'll try to
>> fix it (probably for 3.3, as 3.2.1 is too imminent to fix it there).
> 
> Last time I tried was with gcc-3.0, and it looked like something went
> wrong in the assembly code that was added by the compiler where we were
> returning from a function/method call. I believe it was trying to pop
> data off of the stack that was never added in the first place. I was
> assuming this was related to exception handling.

This could be target/6087 (fixed in 3.2, and IIRC in 3.1 as well).

> This could very well be fixed by now, in fact I just googled and found
> this report which very closely matches what I was seeing.
> 
>     http://www.geocrawler.com/lists/3/GNU/356/0/9429509/
> 
> On the other hand, I'm sure I have not seen any of Coda's source use
> __label__, so it could still be a different problem.

A local label is a label defined with __label__ *in a statement
expression*; statement expressions, while a very cool idea, are utterly
nonportable, so it's highly unlikely that you use them.

> btw. I have by now received at least 3 reports of people that have not
> observed any unusual problems from their gcc-3.x compiled Coda clients.

Good, good :)))

-- 
`The library at my secondary school was there for punishment, I think. I
 did liberate a number of books because I felt sorry for them.'
   --- Marna Gilligan
Received on 2002-11-02 09:03:31