[comp.lang.c] condition expressions

levy@ttrdc.UUCP (Daniel R. Levy) (05/15/87)

In article <874@cc5.bbn.com.BBN.COM>, keesan@cc5.bbn.com.BBN.COM (Morris M. Keesan) writes:
< 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 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.)

Well, this quotation says that the "usual arithmetic conversions" are
performed to bring the expressions to the same type, but it still doesn't
say WHAT type prevails if the two differ; "usual arithmetic conversions"
is begging the question!  (Otherwise, why not quote some other part of the
spec that says what "usual arithmetic conversions" are with respect to members
of tertiary expressions ... oh boy, here we recurse....?)  Why "double" in
the example given: is it supposed to be because double is the type of the
first subexpression, or is it supposed to be because double can accommodate
a char but not vice versa, or what?  This is a valid issue in the case where
there is no lvalue involved:

double x; char y; int i;
...
printf("%lf\n",
/* why wouldn't that be "%c\n", or even (i ? "%lf\n" : "%c\n") ? */
i ? x : y);
-- 
|------------dan levy------------|  Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa,
|         an engihacker @        |		vax135}!ttrdc!ttrda!levy
| at&t computer systems division |  Disclaimer:  try datclaimer.
|--------skokie, illinois--------|

guy@gorodish.UUCP (05/16/87)

> Well, this quotation says that the "usual arithmetic conversions" are
> performed to bring the expressions to the same type, but it still doesn't
> say WHAT type prevails if the two differ; "usual arithmetic conversions"
> is begging the question!

No.  "Usual arithmetic conversions" is merely acting as shorthand for
section 3.2.1.5.

> (Otherwise, why not quote some other part of the spec that says what
> "usual arithmetic conversions" are with respect to members of tertiary
> expressions...

Because, I presume, they felt that it was obvious that the only
rational way to treat the second and third operands of ":" was to
treat them the same way you treated the two operands of "+".  The
situation is certainly similar in the two cases.  I guess this is
another place where the spec needs to be tightened up.  The phrase in
3.2.1.5:

	Many binary operators that expect operands of arithmetic
	type cause conversions and yield result types in a similar
	way.

should, perhaps, be replaced by something like:

	Many non-unary operators that expect operands of arithmetic
	type cause conversions and yield result types in a similar
	way.  Binary operators fall into this category.  The
	conditional operator also falls into this category with
	respect to its second and third operands.

> Why "double" in the example given: is it supposed to be because double
> is the type of the first subexpression, or is it supposed to be because
> double can accommodate a char but not vice versa, or what?

The second of the two, obviously.  This is the same reason why
"double" would be the type of "d + c", where "d" is "double" and "c"
is "char".

> This is a valid issue in the case where there is no lvalue involved:

No, the presence or absence of an "lvalue" has nothing whatsoever to
do with this.

gwyn@brl-smoke.UUCP (05/17/87)

In article <1694@ttrdc.UUCP> levy@ttrdc.UUCP (Daniel R. Levy) writes:
-Well, this quotation says that the "usual arithmetic conversions" are
-performed to bring the expressions to the same type, but it still doesn't
-say WHAT type prevails if the two differ; "usual arithmetic conversions"
-is begging the question!

I don't see the problem.  Consider that (double)+(char) results in
(double).  Intended use of the result has nothing to do with it.

levy@ttrdc.UUCP (Daniel R. Levy) (05/17/87)

In article <19047@sun.uucp>, guy%gorodish@Sun.COM (Guy Harris) writes:
< < Well, this quotation says that the "usual arithmetic conversions" are
< < performed to bring the expressions to the same type, but it still doesn't
< < say WHAT type prevails if the two differ; "usual arithmetic conversions"
< < is begging the question!
< 
< No.  "Usual arithmetic conversions" is merely acting as shorthand for
< section 3.2.1.5.

Does section 3.2.1.5 or some other section actually come out and declare this
"shorthand"?  I'm sorry, but if not, my point stands valid with respect to
the semantics of "English as she is spoken."

< I guess this is
< another place where the spec needs to be tightened up.  The phrase in
< 3.2.1.5:
< 
< 	Many binary operators that expect operands of arithmetic
< 	type cause conversions and yield result types in a similar
< 	way.
< 
< should, perhaps, be replaced by something like:
< 
< 	Many non-unary operators that expect operands of arithmetic
< 	type cause conversions and yield result types in a similar
< 	way.  Binary operators fall into this category.  The
< 	conditional operator also falls into this category with
< 	respect to its second and third operands.

Yes, this is better, but why not be clearer even to the compleat idiot, and
just provide a list of the operators which treat their operands in this
fashion, and indicate which of the operands are affected.

< 
< < Why "double" in the example given: is it supposed to be because double
< < is the type of the first subexpression, or is it supposed to be because
< < double can accommodate a char but not vice versa, or what?
< 
< The second of the two, obviously.  This is the same reason why
< "double" would be the type of "d + c", where "d" is "double" and "c"
< is "char".

N.B.:  I know this.  My question (and the next) was posed rhetorically, as
if I were the Compleat Idiot reading the portion of The Spec which was quoted.

< < This is a valid issue in the case where there is no lvalue involved:
< 
< No, the presence or absence of an "lvalue" has nothing whatsoever to
< do with this.

(I know this too.  See above.)
-- 
|------------dan levy------------|  Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa,
|         an engihacker @        |		vax135}!ttrdc!ttrda!levy
| at&t computer systems division |  Disclaimer:  try datclaimer.
|--------skokie, illinois--------|

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

> Does section 3.2.1.5 or some other section actually come out and declare this
> "shorthand"?  I'm sorry, but if not, my point stands valid with respect to
> the semantics of "English as she is spoken."

Well, yes, it does, so the point doesn't stand.

	3.2.1.5 Usual atithmetic conversions

	    May binary operators <text you can find in my previous
	posting deleted>...  This pattern is called the *usual arithmetic
	conversions*.

	    <description of those conversions>

drw@cullvax.UUCP (Dale Worley) (05/27/87)

levy@ttrdc.UUCP (Daniel R. Levy) writes:
> In article <874@cc5.bbn.com.BBN.COM>, keesan@cc5.bbn.com.BBN.COM (Morris M. Keesan) writes:
> < In article <801@rtech.UUCP> daveb@rtech.UUCP (Dave Brower) writes:
> < <What is the type of the result of evaluating:
> < <	(expr) ? (double) x : (char)y
> <  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."
> 
> Well, this quotation says that the "usual arithmetic conversions" are
> performed to bring the expressions to the same type, but it still doesn't
> say WHAT type prevails if the two differ; "usual arithmetic conversions"
> is begging the question!

The type of the result is implicit in the fact that C types that are
used in expression computation fall in a linear order

int : unsigned int : long int : unsigned long int : double

(Under ANSI, float gets stuck in somewhere -- what if float can't
accomodate long int?)

Thus, given two types, one of them is "bigger" - that's the one that
the conditional expression returns.  For the example, "char" becomes
"int" automatically, and "double" is bigger than that.

(In general, you don't need a linear order, only a "join semilattice";
given any two types there is a minimum type that is "bigger" than both
of them.)

Dale
-- 
Dale Worley		Cullinet Software
UUCP: ...!seismo!harvard!mit-eddie!cullvax!drw
ARPA: cullvax!drw@eddie.mit.edu
Un*x (a generic name for a class of OS's) != Unix (AT&T's brand of such)