[net.lang.c] if vs ?:

saj@iuvax.UUCP (02/15/84)

#N:iuvax:9500002:000:555
iuvax!apratt    Feb 15 00:44:00 1984

In reading through the Lattice C manual, I came across the note that the
compiler detects and discards statements like
	i+j;
which have no side effects. This brings to mind the fact that any expression
is a legal statement. With that in mind, can anybody tell me the likely
difference between
	if ( i )
		j++;
	else
		k++;

and

	i ? j++ : k++ ;

...?  Surely there will be differences in the compiled code.. Can somebody
tell me what they are likely to be?

----

	"Can YOU whistle at 300 baud?"
					-- Allan Pratt
			...decvax!ihnp4!inuxc!iuvax!apratt

keesan@bbncca.ARPA (Morris Keesan) (02/16/84)

------------------------------
It is unclear that there will be any differences between the compiled code for

if (i) j++; else k++;           and         i ? j++ : k++ ;

Certainly, the compiler's discarding of statements with no side effects doesn't
imply anything of the sort.  I recently made a similar enhancement to BBN's C
compiler (based on the Dennis Ritchie PDP-11 C compiler), making it not generate
code for operations with no side effects (such as the statement "i+j;"), and
when I ran the two statements above through it, it produced identical code.  In
my case, this means that I didn't include ?: in my list of "operators with no
side effects".  I see no reason to expect that the implementers of Lattice C
were any less careful.

    An interesting effect of the way I implemented the enhancement is that I
get different code for

if (i) j+1 ; else k+1;          and         i ? j+1 : k+1 ;

because in the first case j+1 and k+1 are statements, and thus get discarded,
leaving an empty "if" framework which gets dropped by the optimizer.  In the
second case, j+1 and k+1 are subexpressions of ?:, and the additions get
generated.  I'm not too concerned about this, since the main reason for my
enhancement was to avoid generating unnecessary conversion code for some casts
being generated internally.  It would be interesting to see what the Lattice C
compiler does with this, though.
-- 
					Morris M. Keesan
					{decvax,linus,wjh12,ima}!bbncca!keesan
					keesan @ BBN-UNIX.ARPA

usenet@abnjh.UUCP (usenet) (02/17/84)

The system V pcc compiler for the 3B20S generates two more
instructions for

	"i ? j++ : k++ ;"

than it does for 

	"if (i) j++ else k++;"

In the former case, it is apparently attempting to get the
value of the result of the expression (namely the prior value
of j or k, depending on the value of i) into a register.
Even though it never uses the value in the register for anything!

It does this regardless of the setting of the "-O" (optimize) flag.
The only effect of the -O flag is to replace jumps to returns by
returns.

Rick Thomas
ihnp4!abnji!rbt   or   ihnp4!abnjh!usenet

guy@rlgvax.UUCP (Guy Harris) (02/18/84)

> The system V pcc compiler for the 3B20S generates two more
> instructions for

> 	"i ? j++ : k++ ;"

> than it does for 

> 	"if (i) j++ else k++;"

> In the former case, it is apparently attempting to get the
> value of the result of the expression (namely the prior value
> of j or k, depending on the value of i) into a register.
> Even though it never uses the value in the register for anything!

> It does this regardless of the setting of the "-O" (optimize) flag.
> The only effect of the -O flag is to replace jumps to returns by
> returns.

Well, if you said

	l = i ? j++ : k++ ;

it would be using the value in question (the previous value of j or k).
Either it's too tricky to teach PCC how to deal with expressions whose
value is being thrown out (I suspect, by the way, that explicitly throwing
the value out by casting to "void" won't help), or it was decided that it
wasn't worth the trouble.  Also, "-O" isn't a full-blown optimizer, it's
a peephole and "final" (to use Bliss-11 compiler terminology) optimizer and
doesn't catch all suboptimal code.

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy

mark@laidbak.UUCP (Mark Brukhartz) (02/21/84)

Some machine-dependent code uses "discarded values" for parameters
to asm() (assembly language) escapes. For example:

	a + b;					/* Assume result goes to r0 */
	asm("	(something using r0)	");	/* Do something funny with r0 */

The "a + b" could just as easily be "a < b ? a++ : b++". Such code
assumes that the compiler and optimizer will not ignore the "unneeded"
statement or value.

Quite a bit of recent Berkeley code uses asm() escapes to generate fast
VAX code. I don't like this any more than you do, but it's something to
keep in mind when considering a change to the compiler.

					Mark Brukhartz
				{allegra,ihnp4,ittral,trsvax}!laidbak!mark

emjej@uokvax.UUCP (02/23/84)

#R:iuvax:9500002:uokvax:3000019:000:1536
uokvax!emjej    Feb 17 11:35:00 1984

/***** uokvax:net.lang.c / iuvax!apratt / 12:44 am  Feb 15, 1984 */
.... With that in mind, can anybody tell me the likely difference between
	if ( i )
		j++;
	else
		k++;

and
	i ? j++ : k++ ;

...?  Surely there will be differences in the compiled code.. Can somebody
tell me what they are likely to be?
/* ---------- */

I can only tell you what the difference would be in my code generator.
The latter code (?:) would generate worse code in this context, since
it looks locally like someone is going to use the results of the conditional
expression. The if/else would look like

	cmp	0,<i>
	jeq	Ln
	inc	1,<j>
	jbr	L(n+1)
Ln:	inc	1,<k>
L(n+1):	...

while the ?: would look like

	cmp	0,<i>
	jeq	Ln
	mov	<j>,t0		a temporary register
	inc	1,<j>
	jbr	L(n+1)
Ln:	mov	<k>,t0
	inc	1,<k>
L(n+1):	...

(The comparison might not be there if we knew that we'd just evaluated i
so as to set flags.) All it means is that I'm not bright enough to notice
that you're not using the old values of j and k for the conditional
expression, and that I'm generating code for a machine whose addressing
modes don't have side-effects. (It was fun to implement post-increment
and decrement so as to avoid unnecessary copies, by the way--you just
remember how much to tweak things just before discarding them. Watch
out for base registers used to access things that you want to compare,
because deferring increments on them may wipe out the condition code!
In that case, just bias the offset by the increment amount and do it
right away.)

						James Jones