Path: utzoo!dciem!nrcaer!cognos!jimp From: jimp@cognos.uucp (Jim Patterson) Newsgroups: comp.lang.c Subject: Re: Structure pointer question Message-ID: <3348@cognos.UUCP> Date: 20 Jun 88 16:23:03 GMT Article-I.D.: cognos.3348 References: <361@teletron.uucp> <8074@brl-smoke.arpa> <4524@haddock.isc.com><4606@haddock.ISC.COM> <5925@aw.20 Jun 88 16:23:03 GMT Reply-To: jimp@cognos.UUCP (Jim Patterson) Organization: Cognos Inc., Ottawa, Canada Lines: 56 In article <5925@aw.sei.cmu.edu> firth@bd.sei.cmu.edu.UUCP (Robert Firth) writes: >In article <4606@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes: > >>It's not a pointer to a completely unspecified type. It's a pointer to a >>struct with unknown contents. (This matters. Although pointer-to-char and >>pointer-to-int might have different internal representations, pointer-to- >>-struct-foo and pointer-to-struct-bar cannot%.) > >This makes no sense to me. Surely a pointer to a struct whose only >component is of type X will use the same representation as a pointer >to a plain X. Either approach is valid. A 'correct' program should not assume that a pointer-to-struct-foo and pointer-to-struct-bar are equivalent. The compiler is therefore free to use different representations. However, on most machines the compiler design is simplified by using a common representation, so in practice the representations are often made equivalent. An example of a compiler which makes all struct pointers equivalent is the DG C compiler. The DG systems are word-oriented (a byte address is 2* the word address, with the extra low-order bit used to address the byte in the word). However, all struct addresses are word addresses, even if they only contain char data. In this case, the cost is only at most a single byte per struct, and only in the relatively obscure cases where a struct consists only of some odd number of bytes of char data. The benefit in simplicity of both the compiler and of programs which use it makes up for this slight cost. A counter-example is the HP SPECTRUM C compiler. The Spectrum is a RISC architecture which has strict alignment rules (e.g. 32-bit ints need 32-bit alignment, 64-bit floats need 64-bit alignment). The C compiler of course ensures this when it allocates its data, but to avoid excessive memory wastage it computes the appropriate alignment for structs on a case by case basis. A struct can therefore have anywhere from 8-bit to 64-bit alignment depending on contents. This won't cause representational problems on the Spectrum because pointers are all effectively byte pointers (only the number of forced low order 0-bits varies). However, it can result in problems if you assume that a struct with a smaller alignment can be replaced by one with a larger alignment. For example, the following code segment could blow up or could work depending on whether Foo happened to be aligned on an even or odd 32-bit boundary. struct foo { long a,b; } Foo; struct bar { double c; }; ((struct bar *)&Foo)->c = 5.0; The bottom line is that strictly speaking, you should not assume that different struct pointers have the same representation. In practice, you will usually get away with it, but someday you may get bit. -- Jim Patterson Cognos Incorporated UUCP:decvax!utzoo!dciem!nrcaer!cognos!jimp P.O. BOX 9707 PHONE:(613)738-1440 3755 Riverside Drive Ottawa, Ont K1G 3Z4