Problem with ()?():() as ending test in for-loop

Ken Stanley kens at attila.WEITEK.COM
Fri May 26 03:12:15 AEST 1989


In article <17722 at mimsy.UUCP>, chris at mimsy.UUCP (Chris Torek) writes:
> instead.  If so, rewriting the test as
> 
> 	((n % 10) != 0 && k > 2) || n < 100
> 
> will probably get around the bug.  (Any valid `logical' [true/false]
> e1?e2:e3 expression can always be transformed this way into (e1&&e2)||e3,
> provided e3 has no side effects.)

Yes, the specific example works.  But, the generalization to "Any valid
logical ..." is not true.  Here is the truth table for these
two expressions:

                    e1?e2:e3                (e1&&e2)||e3
 e1, e2, e3         true                    true
 e1, e2,~e3         true                    true
 e1,~e2, e3         false                   true        <<  NOTE DIFFERENCE
 e1,~e2,~e3         false                   false
~e1, e2, e3         true                    true
~e1, e2,~e3         false                   false
~e1,~e2, e3         true                    true
~e1,~e2,~e3         false                   false



The logical expression (e1?e2:e3) is the same as ((e1 && e2) || (~e1 && e3))
which is not the same as ((e1 && e2) || e3)

The specific example: "((n % 10) != 0 && k > 2) || n < 100" works because
when n = 100, (n % 10) == 0 and ! (n < 100).  However, if the loop increment
were 3 instead of 1, it would not.  In other words, the following two 
statements are not identical:

for (n = 1; ((n % 10) != 0 && k > 2) || n < 100; n += 3) 
for (n = 1; ((n % 10) ? (k > 2) : (n < 100); n += 3) 

Whereas these two statements are identical:

for (n = 1; ((n % 10) != 0 && k > 2) || n < 100; n++)
for (n = 1; ((n % 10) ? (k > 2) : (n < 100); n++)

Ken Stanley



More information about the Comp.lang.c mailing list