TooBored TooBored - 4 months ago 15
C Question

?: ternary conditional operator behaviour when leaving one expression empty

I was writing a console application that would try to "guess" a number by trial and error, it worked fine and all but it left me wondering about a certain part that I wrote absentmindedly,

The code is:

#include <stdio.h>
#include <stdlib.h>

int main()
{
int x,i,a,cc;
for(;;){
scanf("%d",&x);
a=50;
i=100/a;
for(cc=0;;cc++)
{
if(x<a)
{
printf("%d was too big\n",a);
a=a-((100/(i<<=1))?:1);

}
else if (x>a)
{
printf("%d was too small\n",a);
a=a+((100/(i<<=1))?:1);

}
else
{
printf("%d was the right number\n-----------------%d---------------------\n",a,cc);
break;
}
}
}
return 0;
}


More specifically the part that confused me is

a=a+((100/(i<<=1))?:1);
//Code, code
a=a-((100/(i<<=1))?:1);


I used
((100/(i<<=1))?:1)
to make sure that if
100/(i<<=1)
returned 0 (or false) the whole expression would evaluate to 1
((100/(i<<=1))?:***1***)
, and I left the part of the conditional that would work if it was true empty
((100/(i<<=1))? _this space_ :1)
, it seems to work correctly but is there any risk in leaving that part of the conditional empty?

Answer

This is a GNU C extension (see ?: wikipedia entry), so for portability you should explicitly state the second operand.

In the 'true' case, it is returning the result of the conditional.

The following statements are almost equivalent:

a = x ?: y;
a = x ? x : y;

The only difference is in the first statement, x is always evaluated once, whereas in the second, x will be evaluated twice if it is true. So the only difference is when evaluating x has side effects.

Either way, I'd consider this a subtle use of the syntax... and if you have any empathy for those maintaining your code, you should explicitly state the operand. :)

On the other hand, it's a nice little trick for a common use case.

Comments