crash@jc3b21.UUCP (Frank (Crash) Edwards) (09/11/87)
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
throopw@xyzzy.UUCP (09/12/87)
> crash@jc3b21.UUCP (Frank (Crash) Edwards) Frank seems confused between what the language guarantees to do, and what some particular compiler for the language actually does. Or perhaps between what programmers programming in a given language must do, and what compilers for that language must do. > 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"? Nothing at all. It still must be a member, in the sense that for a programmer to be programming in C, that programmer must ensure that it is in fact a member. It's just that some (many) compilers don't enforce this. An analogy: "The manager said that I must be a member to enter the club, but the doorman didn't check my ID. So what happened to that 'must be a member' stuff?" What happened to it is nothing at all... if the manager sees you, he'll be within his rights to boot you out. The compiler (doorman) isn't the same thing as the language standard (manager). And when some other compiler (doorman) *does* check your structure usage (ID) and flag it as erronious (boots you out), you can't point to the first compiler (doorman) as a reason to allow you what you want. > 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.) In fact, K&R are telling you outright that "this *may* happen" *EVEN* *IF* the preceeding types are the same. In other words, K&R said what they said... there's no "should" about it: they just don't guarantee what you think is guaranteed. If you still think it *is* guaranteed, you must look to some other guarantor than K&R. > 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"? Again, "the compiler" (doorman) doesn't care. But the language definition (manager) *does* care, and if you do this, you simply won't be programming in C. So there. -- The place where I come from is a small town. They think so small, they use small words. But not me. I'm smarter than that. I've worked it out. I'll stretch my mouth to let those big words come right out. --- from "Big Time" by Peter Gabriel -- Wayne Throop <the-known-world>!mcnc!rti!xyzzy!throopw
gwyn@brl-smoke.UUCP (09/13/87)
In article <167@jc3b21.UUCP> crash@jc3b21.UUCP (Frank (Crash) Edwards) writes: >Given the following definition, should the reference "msg.m_union.m_from" >be a legal reference to the member of the "pckt" structure? No. You forgot to include ".pckt" in the reference. >And should >it reference the first location of m_union or the first location of pckt? Assuming you fix that, it references the "m_from" member, naturally. > "Such constructions are non-portable." Yup, they were allowed by a particular implementation of C, not by the language rules. >First of all, this paragraph should read, "but if preceding member *types* >differ". No, K&R had it right. If preceding members (member names) differ, the result is non-portable. Some compilers won't even allow it. Why don't you just do this the right way (fully-qualified member path), rather than try to cheat?
henry@utzoo.UUCP (Henry Spencer) (09/13/87)
> Again [K&R] reference "the compiler" -- as if only *one* compiler existed!
You are forgetting how *old* K&R is. There *was* only one, for all practical
purposes, when that was written. (Remember, much of Appendix A predates even
the book's copyright date by quite a bit.)
--
"There's a lot more to do in space | Henry Spencer @ U of Toronto Zoology
than sending people to Mars." --Bova | {allegra,ihnp4,decvax,utai}!utzoo!henry
peter@sugar.UUCP (09/14/87)
In article <167@jc3b21.UUCP>, crash@jc3b21.UUCP (Frank (Crash) Edwards) writes: > "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. > Again the reference "the compiler" -- as if only *one* compiler existed! The book was written when basically only one compiler existed. The compiler described is the PDP-11 K&R compiler. Most modern 'C' compilers do check on the types of the structure and the member and will complain. Thus the construction is non-portable. Whenever K&R talks about "the compiler", that should cue you to regard the associated text as being suspect unless you're using a PDP-11 running version 6 or version 7 UNIX. -- -- Peter da Silva `-_-' ...!hoptoad!academ!uhnix1!sugar!peter -- 'U` ^^^^^^^^^^^^^^ Not seismo!soma (blush)