[comp.lang.c] NULL pointers as arguments, really condition expressions

daveb@rtech.UUCP (Dave Brower) (05/04/87)

In article <17780@sun.uucp> guy%gorodish@Sun.COM (Guy Harris) writes:
>This means that if "cp" is of type "char *", then the expression
>
>	0 ? cp : 0
>
>has "the type of the pointer", namely "char *", while if "sxp" is of
>type "struct x *", the expression
>
>	0 ? sxp : 0
>
>has the type "struct x *".  Both expressions yield null pointers, and
>both expressions have different types.

Which reminds me of a general problem with the conditional operator.
What is the type of the result of evaluating:

	(expr) ? (double) x : (char)y

I believe it is undefined.   One could adopt a number of possible
rules for interpretation:

	* Take the type of the true expression as the type of the whole.
	* Take the type of the false expression...
	* Take the type of the lval, if any.
	* Take the type of the "biggest" type of the true or false expr.
	* Call it an error.

I'm inclined to call it an error.  Thoughts, anyone?

-dB
-- 
{amdahl, sun, mtxinu, cbosgd}!rtech!daveb daveb@rtech.uucp

guy%gorodish@Sun.COM (Guy Harris) (05/04/87)

> What is the type of the result of evaluating:
> 
> 	(expr) ? (double) x : (char)y
> 
> I believe it is undefined.

Well, you're wrong.

> One could adopt a number of possible rules for interpretation:
> 
> 	* Take the type of the true expression as the type of the whole.
> 	* Take the type of the false expression...
> 	* Take the type of the lval, if any.
> 	* Take the type of the "biggest" type of the true or false expr.
> 	* Call it an error.
> 
> I'm inclined to call it an error.  Thoughts, anyone?

"Take the type of the 'biggest' type of the true or false expr" comes
closest to the specified rules.  From K&R:

	7.13 Conditional operator

	...If possible, the usual arithmetic conversions are
	performed to bring the second and third expressions to a
	common type; otherwise, if both are pointers of the same
	type, the result has the common type; otherwise, one must be
	a pointer and the other the constant 0, and the result has
	the type of the pointer.

and from the October 1, 1986 ANSI C draft:

	3.3.15 Conditional operator

	...

	   The first operand shall have scalar type.  Both the second
	and third operands may have arithmetic type, or may have the
	same structure, union, or pointer type, or may be void
	expressions.  In addition, one may be a pointer and the other
	a null pointer constant, or one may be a pointer to an object
	and the other a pointer to 'void'.

	...

	   If both the second and third operands have arithmetic type,
	the usual arithmetic conversions are performed to bring them
	to the same type, and the result has that type.  If both the
	operands have structure, union, or pointer type, the result
	has that type.  If both the operands are void expressions,
	the result is a void expression.  If one of the operands is a
	pointer to an object and the other is a pointer to 'void',
	the pointer to an object is converted to type pointer to
	'void', and the result has that type.  If one operand is a
	pointer and the other operand a null pointer constant, the
	result has the type of the pointer.

keesan@cc5.bbn.com.BBN.COM (Morris M. Keesan) (05/05/87)

In article <801@rtech.UUCP> daveb@rtech.UUCP (Dave Brower) writes:
>Which reminds me of a general problem with the conditional operator.
>What is the type of the result of evaluating:
>
>	(expr) ? (double) x : (char)y
>
>I believe it is undefined.   One could adopt a number of possible
>rules for interpretation:
>
>           . . . [possible rules omitted for brevity]
>
>I'm inclined to call it an error.  Thoughts, anyone?

The type of the expression is well defined.  K&R say (7.13, p. 191), "If
possible, the usual arithmetic conversions are performed to bring the second 
and third expressions to a common type."  They don't say explicitly that
this type is the type of the expression, but that's implicit in the rest of the
definition.  The Draft Proposed American National Standard is even clearer:
"If both . . . have arithmetic type, the usual arithmetic conversions are
performed to bring them to the same type and the result has that type."

In the example given, the result of the expression is either (double)x or
(double)(int)(char)y, following the order of conversions specified by K&R.
(Semantics of conversions is not specified as precisely in the DPANS.)
-- 
Morris M. Keesan
keesan@cci.bbn.com
{harvard,decvax,ihnp4,etc.}!bbnccv!keesan

rbutterworth@orchid.UUCP (05/05/87)

In article <801@rtech.UUCP>, daveb@rtech.UUCP (Dave Brower) writes:
> Which reminds me of a general problem with the conditional operator.
> What is the type of the result of evaluating:
>     (expr) ? (double) x : (char)y
>     * Take the type of the true expression as the type of the whole.
>     * Take the type of the false expression...
>     * Take the type of the lval, if any.
>     * Take the type of the "biggest" type of the true or false expr.
>     * Call it an error.

I'd call it an error.  But how about
    intptr = (expr) ? void_star_func() : float_star_func() ;

I haven't checked the latest draft, but an earlier ANSI draft
indicated that the type of ?(void*):(type*) would be (void*).

This is definitely not the way it should be, as the above
example would compile and lint cleanly even though it is
wrong.  I hope ANSI has or will change it to indicate that
the result of a ":" with a (void*) is the type of the other
pointer (and that other mixed used of ":" would be treated
according to the usual widening and promotion rules).