Path: utzoo!mnetor!uunet!seismo!sundc!pitstop!sun!amdcad!ames!hao!gatech!purdue!i.cc.purdue.edu!j.cc.purdue.edu!pur-ee!hankd From: hankd@pur-ee.UUCP (Hank Dietz) Newsgroups: comp.arch Subject: Re: RISC data alignment Message-ID: <7572@pur-ee.UUCP> Date: 18 Feb 88 22:55:38 GMT References: <2635@calmasd.GE.COM> <28200092@ccvaxa> <496@ecrcvax.UUCP> <286@bacchus.DEC.COM> Organization: Purdue University Engineering Computer Network Lines: 63 Summary: when a struct isn't a struct In article <286@bacchus.DEC.COM>, alverson@decwrl.dec.com (Robert Alverson) writes: > In article <3001@bloom-beacon.MIT.EDU> jfc@athena.mit.edu (John F Carr) writes: > > > > (&(s.a) - &(s.b)) == 1 it is making an unsupported assumption. Can > >someone post an example of a program which is portable and depends on > >the K&R rule quoted above? > > How about this: > > typedef struct VarStr_str { int len; char str[1]; } VarStr; > > VarStr *MakStr(s) char *s; { > VarStr *p = malloc(sizeof(VarStr) + strlen(s)); > strcpy(p->str, s); > return p; > } Portable? Try again. According to C, malloc does not exist -- it is just another user function. When you use malloc, you take advantage of a hole in the C type system (i.e., the very deliberate hole called type casting -- which you incidentally forgot in your use of malloc). I'm not saying the above hack isn't useful, but that your "struct" doesn't work as a struct. For example, C permits us to perform struct assignment, but you can't use it for a struct like yours because it will NOT COPY THE ELEMENTS WHICH WERE NOT DECLARED CORRECTLY -- i.e., it will copy only str[0] and not the whole string. The same is true of returning a struct or passing it by value. And sizeof is also wrong. You are trying to justify the need to maintain order of a struct's members by declaring something as a struct even though it can't be treated as one. Unfortunately, there is no way within C's type system to declare the above, so a kludge is needed. Compare your kludge to the Refined C concept of a paramtype (a parameterized struct type), which allows a variable-sized struct to be declared and treated as a first-class data object. (I can supply references and/or papers on Refined C if you're interested in how this works.) Aside from the above argument, it is possible for a compiler to determine when the order of members in a struct could be significant, and to rearrange only when the order can be changed without altering the program's meaning. For example, your struct only has to have the last field last... the order of the other fields doesn't matter. In code where the programmer may have sloppily used the struct address as the address of the first member, the compiler can constrain the first member to remain first. Of course, I'm not saying that it is easy to do, but just that a compiler can do it. (Minimizing space, or optimizing memory reference pattern, by cerfully rearranging struct members is something I have taught in fair detail in my graduate compilers courses for the past 4 or 5 years.) In summary, let's not try to encourage kludges as principles of language design. If you must write code which depends on the order, be aware that you are doing it outside of the language's type system, and that compilers will tend to generate lousy code for it because they have to make safe assumptions about what undecipherable (to the compiler) things you've done.