Two standards problems

Clive Feather clive at ixi.UUCP
Sat Jun 17 00:46:17 AEST 1989


In article <183 at ixi.UUCP> I asked two questions on ANSI C.
My thanks to Doug Gwyn, David Prosser, and Pardo for answering.

Now, the sequel. Just to be confusing, the topics are in reverse order.
Once again, I only want ANSI standard answers.

First topic (structure alignment)
=================================

I have three structure types: t_all, t_first, and t_last. The initial fields
of t_all and t_first are the same. Suppose I define the following structured
types:

    typedef                      typedef
    {                            {
        t_all all;                   t_first first;
    }                                t_last  last;
    t_whole;                     }
                                 t_joined;

and the union:

    union
    {
        t_whole  whole;
        t_joined joined;
    }
    u;

Then ANSI requires that a value written into one of the common fields of
u.whole.all be readable out of the same field in u.joined.first.

My questions:

(Q8)  Do the names of the common initial fields of t_all and t_first have to
      be the same for this to work, or is it sufficient for the types to be
      identical ?
(Q9)  It seems to me that, since the union might only appear in one source
      file, whilst the structures might be used in several, that the padding
      of a structure depend *only* on the types of the fields of the
      structure. Is this so ? If so, how do I get X3J11 to mandate it.

I have many other structure types. All are of the form:

    typedef
    {
        t_part_1 part_1;
        t_part_2 part_2;
        t_part_2 part_3;
    }
    *t_3_parts;

I.e. I have t_1_parts, t_2_parts, t_3_parts, and so on; they are all pointers to
structures, and all begin with a t_part_1 field. Further, all these field types
are actually structures.

(Q10) Do all the t_n_parts types have the same alignment requirements ? For
      historical reasons, there are many functions which take an argument of
      type t_1_parts, which is actually a value of one of the other types cast
      correctly. These functions only access the part_1 fields.


Second topic (offsets)
======================

The Xt Intrinsics have a macro XtOffset. This is similar to the offsetof
macro defined by ANSI. The call "XtOffset (T *, field)" is equivalent to
"offsetof (T, field)", except that in the former the field may contain
dot operators, and the type specified will normally be a typedefed pointer,
rather than a construction with a *.

(Q11) Can offsetof take "field1.field2" as its second argument ?
(Q12) If not, can I add the offset of the sub-structure in the main one
      and the field in the substructure to get the right effect ?
      (I.e. can I use offsetof (T, field1) + offsetof (SUBT, field2)
      to get the effect of offsetof (T, field1.field2).

The Intrinsics, in effect, have several functions which look similar to
the following:

    void GetValue (t_1_parts object, size_t size, offset_t offset, int magic)
    /* I assume that offsetof returns an offset_t */
    /* See above for t_1_parts, and note Q10 */
    {
        void *value_ptr;

        /*
            The caller has some structure of the type pointed to by one of
            the t_n_parts types; call this structure S and its type ST. In
            addition, S has some field F of type FT (F may be a field of a
            field of S). The caller will guarantee that:

                object == (t_1_parts *) &S
                size   == sizeof (FT)
                offset == XtOffset (ST *, F)
        */

        /*
            This comment is replaced by code which takes the value magic and
            sets value_ptr to the address of a value of type FT, cast to
            void *.
        */

        /*
            The next statement *should*, in my opinion, carry out the following
            assignment:

                S.F = * (FT *) value_ptr;

            or if you prefer:

                ((ST *) object)->F = * (FT *) value_ptr;
        */

        memcpy ((void *) object + offset, value_ptr, size);
    }

(Q13) Does ANSI guarantee that, given the assertions in the various comments,
      the call to memcpy will do the assignment ?
(Q14) If not, how do I write the last part of GetValue ?


Once again, my thanks (in advance) to those that answer.
-- 
Clive D.W. Feather
IXI Limited
clive at ixi.uucp
...!uunet!ukc!ixi!clive (riskier)



More information about the Comp.std.c mailing list