Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site dg_rtp.UUCP Path: utzoo!watmath!clyde!burl!ulysses!gamma!epsilon!zeta!sabre!petrus!bellcore!decvax!mcnc!rti-sel!dg_rtp!throopw From: throopw@dg_rtp.UUCP (Wayne Throop) Newsgroups: net.lang.c Subject: Re: Casting a postdecrement operand Message-ID: <388@dg_rtp.UUCP> Date: Fri, 6-Jun-86 17:28:38 EDT Article-I.D.: dg_rtp.388 Posted: Fri Jun 6 17:28:38 1986 Date-Received: Sun, 8-Jun-86 04:23:33 EDT References: <114@romp.UUCP> <2842@utcsri.UUCP> <378@dg_rtp.UUCP> <2882@utcsri.UUCP> Lines: 92 Summary: references and reasoning as to why ((T*)P)++ is illegal > greg@utcsri.UUCP (Gregory Smith) > I stand corrected. I couldn't find anything explicitly forbidding or > allowing this in K&R, ( I still can't ) so I gave that compiler the > benefit of the doubt, without trying it here. For those interested, here are the places that make ((T *)P)++ illegal. First, in K&R, two places. In the reference section, 7.2, unary operators: An expression preceeded by the parenthesized name of a data type causes conversion of the value of the expression to the named type. This construction is called a cast. Note that the *value* is *converted*. K&R are careful to call lvalues lvalues, and the note that a cast works on the value of the expression is noteworthy. Note also that this value is *converted*. It is *not* "taken as a new type". As an interesting digression, this is probably the source of much confusion over casts, since many think that they are conversion sometimes, and "look at T1-type bits through T2-colored glasses" other times. This is *not* the case... a cast is *always* a conversion. In C there are only two ways to take T1-typed-bits as if they were T2-typed-bits. Put the bits into a union of T1 and T2, or cast a pointer to them. (Well, they are the only two ways I could think of, anyhow.) Then note, in 5, objects and lvalues: The discussion of each operator below indicates whether it expects lvalue operands and whether it yields an lvalue. Casts do not state that they yield lvalues, and postincrement expects one. So the combination is semantically illegal according to K&R. In Harbison and Steele, things are simpler. In chapter seven, they list the operators that yield lvalues, which are e1[e2], (e) {if e is lvalue}, e.name {if e is lvalue} e->name, and *e and conclude the paragraph, saying No other form of expression can produce an lvalue. And in the same section, they state that postincrement requires an lvalue. The ANSI draft says in section 3.4 Note: A cast does not return an lvalue. As I say, Father, Son and Holy Ghost all agree on this point. > Reasonable semantics > could be defined for the operation, but I don't know how useful it is. On first glance, it *does* seem reasonable. But upon more detailed thought, it turns out not to be the case. The whole point is that reasonable semantics *cannot* be defined for the operation in a machine independant way. The reasoning of the ANSI folks is spelled out in the May '86 Dr. Dobb's Journal on page 20 in a section titled "Beating Dead Horses" if you want to look it up, but the short form of this argument is fairly simple. You say that ((T *)P)++ can be given reasonable semantics. This either means that pointers are drastically different from other types (in ways that are inconvenient and/or arbitrary), or this construction can also be given reasonable semantics: ((T)L)++ Filling in something concrete for the type and the lvalue, and assuming that "i" is an integer lvalue: ((float)i)++ Do you really want to contend that this is reasonable? If so, what does it mean? Either the semantics of C must be made very irregular and strange to allow ((T *)P)++, or the notion of any cast being an lvalue must be discarded. In addition to complexity and irregularity, possible semantics of casts of lvalues *being* lvalues are extremely machine dependant (in particular (in current implementations that allow them), the pointer cases depend on the pointer format for all pointer types being identical). This is *not* something that is "reasonable" to add to an allegedly machine independant language. -- Wayne Throop !mcnc!rti-sel!dg_rtp!throopw