Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!husc6!rutgers!mtune!codas!usfvax2!jc3b21!crash From: crash@jc3b21.UUCP (Frank (Crash) Edwards) Newsgroups: comp.lang.c Subject: Unions that generate offsets (?) Message-ID: <167@jc3b21.UUCP> Date: Fri, 11-Sep-87 07:17:58 EDT Article-I.D.: jc3b21.167 Posted: Fri Sep 11 07:17:58 1987 Date-Received: Sat, 12-Sep-87 19:56:43 EDT Organization: Transportation Systems Consulting, Palm Harbor, FL Lines: 71 Keywords: union structure offset Summary: Is_it/should_it_be legal to omit a union variable in a ref? Okay all, I'm ready for the flames from this one! Given the following definition, should the reference "msg.m_union.m_from" be a legal reference to the member of the "pckt" structure? And should it reference the first location of m_union or the first location of pckt? The compiler generated offset for m_from is 0. Inside a union, all members have the offset 0. So "m_union.pckt.m_from" is equivalent to "m_union.m_from": struct { long mtype; /* Message type... */ union { char text[80]; /* For sending textual message */ struct { long m_from; /* Data contained in a packet */ ushort m_cmnd; char data[40]; } pckt; } m_union; } msg; K&R says that the syntax rules for unions are the same as for structures. And that in a structure reference ('.' or '->') the name on the right *must be a member* of the structure named or pointed to by the expression on the left (the accent is mine). PP 14.1, K&R: "To allow an escape from the typing rules, this restriction is not strictly enforced by the compiler. In fact, any lvalue is allowed before ., and that lvalue is then assumed to have the form of the structure of which the name on the right is a member." So what happened to "must be a member"? "Such constructions are non-portable." Which such constructions? The ones just defined for the '.' member reference or the ones for '->'? Or does it matter? PP 8.5, K&R: "Actually, the compiler checks only that a name in two different structures has the same type and offset in both, but if preceding members differ the construction is non-portable." First of all, this paragraph should read, "but if preceding member *types* differ". Since the compiler checks offsets, the construction is non- portable only if the offset might change during porting. This will not happen if the preceding *types* remain the same, regardless of whether they are the same members. (I know -- a little picky maybe.) Again the reference "the compiler" -- as if only *one* compiler existed! Oh well. If the compiler only checks for type and offset, why should it care if I use the union member (in this example "m_from") as an offset to "msg"? And is this offset non-portable? After all, I'm using an offset created by the compiler. Maybe the term "portable" in paragraph 14.1 actually means "compilable", since the other compiler may not adhere to K&R? Well, I'm ready for your opinions... flames... experiences... (I particularly expect to hear from old instructors who thought that they had taught me better than to write code like that!) --------------------------------------------------------------------------- Frank J. Edwards, Programmer UUCP: codas!usfvax2!jc3b21!tsc3b21!crash Transportation Systems Phone: (813) 785-0583 Consulting Corporation 1680 US Hwy Alternate 19 Palm Harbor, FL 34683