throopw@dg_rtp.UUCP (Wayne Throop) (11/09/86)
> leichter@yale.UUCP (Jerry Leichter) > I can think of no particular use for casting of arbitrary lvalues, but in > situations as above, the following definition for a cast argument to op= > would be handy: > (type)a op= b > shall mean: > a = (type)a op b > (except that a is only evaluated once). Good idea. Or rather, "less bad than most such ideas". I will end up arguing against this, but it is by far the best possible interpretation that allows casts as lvalues I've seen. On the good side, the only real justification for all this hoo-hah about allowing cast values to be lvalues sometimes is an attempt to evaluate some expressions only once. It is therefore quite apt to deal with this as a generalization of the idea of op= rather than a modification of the notion of lvalueness. Also, this idea generalizes to any unary operator that normally destroys lvalueness, not just casts, for example -a += 1; /* negate a and add 1 */ sizeof(a) *= 10; /* assign a peculiar constant to a */ and so on and on. This (especially the cast cases) would allow a small number of additional useful cases to get by with only one "actual" evaluation while multiple "conceptual" evaluations occur. On the bad side, no matter how you try, there will be some cases where more than one actual evaluation will be needed to express the conceptual evaluation one has in mind as a single C expression. One has to draw the line somewhere. C currently draws it at the simplest place: right at any operator that conceptually produces a distinct new value, such as casts, negations, sizeofs and the like. All in all, the standard C position seems like a very good place to draw this line. The point is, if somebody says ++((type *) p) or ((type *)p)++ Jerry's idea says they really mean p=((type *)p)+1 or (q=p,p=((type *)p)+1,q) The question is, is the shorthand worth it in this particular case? The case folks clamor for this is where p is a simple pointer variable (often a register variable to boot), so the concern surely isn't for the efficency of the dual evaluation. And it doesn't seem too likely that the concern is for clarity, either, since (p=((type *)p)+1) is pretty clear. The extra "q" that muddies up the postincrement case isn't even necessary if the increment is factored out of the single expression, as it could easily be. A little more about clarity: why should Jerry's idea be rejected on grounds of no gained clarity? After all, the binary abbreviations implemented op= really help clarity. Why not extend this to unary operators also? My answer: the binary case was indeed a big clarity win, because such expressions (a += b, for example) more closely matched how we think of such things... we think of it as "add b to a", not "assign the sum of a and b to a". But in the case of ((type *)p) += 1, there really is a conversion operation on the pointer, then an increment, then an assignment (and the assignment implies a conversion back!!!). Compressing two conversions and an increment into the assignment in this abbreviation is misleading, and doesn't really reflect how we think (or how we ought to think) of what is going on. I expect there are those that disagree with me, and I suppose I wouldn't be totally aghast if Jerry's idea were adopted by X3J11. But it just doesn't seem all that necessary, and it is a slightly misleading syntax. -- MICHAELMAS: "You don't think my theory holds water?" DOMINO: "A bathtub will hold water. A canteen is usually sufficent." --- from "MICHAELMAS" by Algis Budrys -- Wayne Throop <the-known-world>!mcnc!rti-sel!dg_rtp!throopw