kpmartin@watmath.UUCP (Kevin Martin) (01/05/85)
There seem to be people who are saying, effectively, if the language user doesn't care about struct element alignment, he/she also deson't care about element ordering (you care about alignment for device registers, which are machine dependant already, right?). The problem is, that this isn't true. There are many programs which believe that two structures with the same initial set of elements have the same ordering for those elements. This prevents the compiler from (by default) re-ordering the elements. In other words, it is possible for the programmer to care about the order, but not the alignment, of struct fields. Kevin Martin, UofW Software Development Group
Mark.Tucker@CMU-CS-GANDALF.ARPA (01/08/85)
>> There are many programs which believe that two structures with the same >> initial set of elements have the same ordering for those elements. > >Fie! For shame! It was for this reason (among others) that unions >and separate name spaces among structs were born. Having two structs >with the same initial set of elements -- and trusting them to stay >that way, even through your novice programmer's "fixes" and the new >A. E. Neumann C Compiler XXX -- isn't all that reliable. > >Joe Yao (UUCP!seismo!hadron!jsdy / hadron!jsdy@seismo.ARPA) Sigh, until you give me a subclass mechanism that ensures that the representation of two data types share a common prefix, I'll rely on this compiler hack. Yes, you can declare a new type to represent the common prefix part, but a proliferation of new little types can also confuse the innocent. typedef struct{ foo a,b; } prefix; typedef struct{ prefix p; < t1 specific> bar c; } t1; typedef struct{ prefix p; < t2 specific > baz d; } t2; .... aT1.p.a .... aT1.c You could fix the lack of uniformity in using shared-vs-unique fields by having more control over the naming environment. For instance, you could define typedef OPEN struct{...} prefix; where the "OPEN" modifier allows unqualified access to fields defined in the the type "prefix." Thus, when fields of type prefix are defined, the namespaces of "prefix" and those of the record being defined arenot disjoint. Then, once better control over names are in place, you can introduce PUBLIC, PRIVATE, OPAQUE and get clusters.... -- Mark Tucker
ekb@link.UUCP (Eric K. Bustad) (01/12/85)
> >> There are many programs which believe that two structures with the same > >> initial set of elements have the same ordering for those elements. > > > >Fie! For shame! It was for this reason (among others) that unions > >and separate name spaces among structs were born. Having two structs > >with the same initial set of elements -- and trusting them to stay > >that way, even through your novice programmer's "fixes" and the new > >A. E. Neumann C Compiler XXX -- isn't all that reliable. > > > >Joe Yao (UUCP!seismo!hadron!jsdy / hadron!jsdy@seismo.ARPA) > > Sigh, > until you give me a subclass mechanism that ensures that the > representation of two data types share a common prefix, I'll rely on this > compiler hack. Yes, you can declare a new type to represent the common > prefix part, but a proliferation of new little types can also confuse the > innocent. > . . . > > -- Mark Tucker I suspect that Joe had something like this in mind: #define T1 0 #define T2 1 typedef struct { int subclass; /* either T1 or T2 */ foo a,b; union { struct { foo c bar d; } t1; struct { foz c; baz e; } t2; } noncom; } bigclass; bigclass aT1 = { T1, <initial values for other common fields> }; .... aT1.a if (aT1.subclass == T1) { .... aT1.noncom.t1.c .... } The referencing of non-common fields does get rather ugly, but this will certainly ensure that T1 and T2 structures have the same prefix. = Eric Bustad (AT&T Bell Laboratories, Holmdel NJ) +1(201)949-6257 ihnp4!eric.bustad or link!ekb
ka@hou3c.UUCP (Kenneth Almquist) (01/12/85)
There are two problems with using unions to deal with elements shared between more than one structure. As an example, consider the System V message system call. Each message begins with a long integer specifying the message type; the contents of the rest of the message are left to the applications programmer. Thus if we used a union to declare these messages, we would have: struct message { long m_type; union { struct msg1 msg1; struct msg2 msg2; ... struct msgn msgn; } m_union; }; Two considerations make this impractical. One is administrative; every time a new program was written using the message system call, the union would grow and the kernel would have to be recompiled (especially tough for folks with binary only licenses). The second problem is technical; there is no portable way to allocate only the amount of memory needed for a given message. Allocating "sizeof(struct message)" bytes for each message may be intolerably inefficient. It is in part for these reasons that C compilers are not allowed to re- order structure members. Currently messages can be handled conveniently by declaring structures that will begin with a long since C will leave the type at the beginning of the structure where the programmer put it. > > >Having two structs > > >with the same initial set of elements -- and trusting them to stay > > >that way, even through your novice programmer's "fixes" and the new > > >A. E. Neumann C Compiler XXX -- isn't all that reliable. A novice programmer or a nonworking compiler can break any code. I am not convinced that sharing structure elements is an exceptionally confusing practice (at least not by C standards :-)). Kenneth Almquist