Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!iuvax!watmath!rbutterworth From: rbutterworth@watmath.waterloo.edu (Ray Butterworth) Newsgroups: comp.std.c Subject: C's triadic operator. Message-ID: <26212@watmath.waterloo.edu> Date: 15 May 89 15:28:46 GMT Distribution: comp Organization: U of Waterloo, Ontario Lines: 59 The Standard has some rules about combining pointer types. With diadic operators they are fairly obvious and reasonable: - If one operand is a pointer and the other is the constant 0, the 0 will be coerced to the same type as the pointer. - If one operand is a pointer to void, and the other is a pointer to some other type, the void pointer will be coerced to the same type as the other pointer. With triadic operators (i.e. c?e1:e2) we have: - If both expressions are pointers of compatible types the pointers will be coerced to point to the same type with the union of any qualifiers of the pointed at objects. - If one expression is a pointer and the other is the constant 0, the 0 will be coerced to the same type as the pointer. - If one expression is a pointer to void and the other is any arbitrary type, the pointer to void is coerced to that type, and the result will have the union of any pointed at qualifiers. Now, all of these rules seem obvious, reasonable, and useful. Unfortunately that last rule is not the one in the Standard. What it has is: - If one expression is a pointer to (possibly qualified) void and the other is any arbitrary type, the arbitrary pointer is coerced to be an unqualified pointer to void. Does that seem obvious, reasonable, or useful to anyone out there? The Rationale gives no justification for this behaviour. e.g. extern int cond1; extern int cond2; extern Type *ap; extern void const volatile *vp; extern short const *scp; extern float volatile *fvp; ap = cond ? scp : ( cond2 ? fvp : vp ); Now this legally assigns a value of type (pointer to one of constant volatile void, short constant, or float volatile ) to any arbitrary type pointer. Not only that, as far as I know, the compiler is not even allowed to issue any warnings about how stupid this request is. (Of course if "vp" were replaced by "0", or even by "(void const volatile *)0", there would be lots of error messages produced.) And for compiler implementors, this requirement creates extra work since one can't simply pass the two pointer types to a function that does the standard pointer type coersions. Since the Rationale has nothing to say about this, can someone on the Comittee tell us why such strange behaviour with "?:" is required?