From: mikes@Ingres.COM (Mike Schilling)
Newsgroups: comp.std.c
Subject: Structure walking
Date: 25 Jan 93 21:35:43 GMT
Article-I.D.: pony.1993Jan25.213543.25499

Background:  We'd like to store data in arrays of various structures
in a platform-independent format so that we can subsequently retrieve them
on various different platforms.  We don't want to write a separate routine
for each structure type.  Instead, we propose to store a template
indicating the type of each member in the structure being encoded,
followed by a portable representation of each scalar; a single
general-purpose routine would read or write an array of structures,
driven by the template.

The tricky part is inferring the offset of each member within the structure.

Question 1:  Are the following assumptions valid for all C compilers?
For (c)-(f), assume that the structure contains only scalar members.

(a) Each scalar type has an unambiguous alignment requirement.
(b) Each scalar type's alignment requirement is a power of two.
(c) The offset of the first member of a structure is 0.
(d) The offset of the (n+1)th member of a structure is the offset of
    the nth member of the structure, plus the size of the nth member,
    rounded up to the alignment requirement of the type of the (n+1)th member.
(e) The alignment required by the structure is equal to the most restrictive
    alignment of any of its members.
(f) The size of the structure is the offset of the last member of the structure,
    plus the size of the last member, rounded up to alignment required
    by the structure.

It appears that (a), (c), and (d) (at least) must be true for ANSI-compliant
C compilers; the May '86 draft says the following:

    Each non-bit-field member of a structure or union object is aligned in an
    implementation-defined manner appropriate to its type.

    Within a structure object, the non-bit-field members and the units in which
    bit-fields reside have addresses that increase in the order in which they
    are declared.  A pointer to a structure object, suitably cast, points to its
    initial member or, if it is a bit-field, to the unit in which it resides.
    There may therefore be unnamed holes within or at the end of a structure,
    but not at its beginning, nor more than necessary to achieve appropriate
    alignment.

Question 2:  Can the assumptions in question 1 be generalized to include
structures which contain nested structures?  Equivalently: if we "flatten"
a structure (eliminate all nesting), will that leave its size, alignment
requirements, and the offsets of its scalar members unchanged?

Question 3:  On at least one platform (Data General MV series minis),
pointers to characters were represented diferently from pointers to anything
else (really a byte pointer vs. word pointer distinction), so you had 
to be very careful about how you cast pointers. 
On such platforms, how are pointers to structures represented?  Does 
it depend on the type of the structure?
In particular, consider a structure whose sole member is a character.  
Since pointers to all structures were represented as word pointers
on those DG machines, this structure had to be word aligned, even though its
contents only demanded byte alignment.  This violates 1e above.  Is the 
assumption invalid, or did the compiler (which didn't claim to be 
ANSI) non-conforming in that respect?

Mike
----------------------------------------------------------------------------
mikes@ingres.com = Mike Schilling, INGRES, An ASK Group Company, Alameda, CA
Just machines that make big decisions,
Programmed by fellows with compassion and vision.	-- Donald Fagen, "IGY"
Newsgroups: comp.std.c