yukapuka
yukapuka

Reputation: 97

Conditional operator unary in C

Can anyone explain to me or tell me how to fix this coding issue i have with conditional operator

it seems to always skip the conditional operator and just print out the second option even when i change server to be 0 or 1

and it always prints out the second option SetB then SetA

why does this not work? it is some kind of semantic error? or logical error?

#include <stdio.h>
#include <limits.h>

int main(int argc, char *argv[]){

   int ch = -191;
   int x = UINT_MAX;
   int setA[5]={-1,-1,-1,-1,-1};
   int setB[5]={-2,-2,-2,-2,-2};
   int server = 1;
   int i=2;

   printf("%d %d\n",server==1?setA[i],setB[i]:setB[i],setA[i]);
   printf("%d %d\n",server==0?setA[i],setB[i]:setB[i],setA[i]);


  // printf("%u\n%u\n",ch,x);

}

Upvotes: 1

Views: 165

Answers (4)

M.M
M.M

Reputation: 141554

The grammar for the ternary operator is: condition ? expression : expression

In your code the first expression is setA[i], setB[i] and the second expression is setB[i]. Due to the way the language grammar works, the final comma is an argument separator (not a part of the second expression), so your code is equivalent to:

int a = (server == 1) ? setB[i] : setB[i];
printf("%d %d\n", a, setA[i]);

which of course is the same as:

printf("%d %d\n", setB[i], setA[i]);

so you always get the same result regardless of the condition.


If you are going to have many similar lines in a block of code, one possible solution is to set up some set aliases based on the current server:

// do this once:
int *set0, *set1;
if ( server == 1 )
    set0 = setA, set1 = setB;
else
    set0 = setB, set1 = setA;

// then use it like this    
printf("%d %d\n", set0[i], set1[i]);

Upvotes: 5

R Sahu
R Sahu

Reputation: 206567

The expression

server==1?setA[i],setB[i]:setB[i],setA[i]

is equivalent to:

(server==1? (setA[i],setB[i]) : setB[i]), setA[i])

which is equivalent to

(server==1? setB[i] : setB[i]), setA[i]

which is equivalent to

setB[i], setA[i]

But, that's not what you wanted. What you wanted was:

if ( server == 1 )
{
  printf("%d %d\n", setA[i], setB[i]);
}
else if ( server == 0 )
{
  printf("%d %d\n", setB[i], setA[i]);
}

Upvotes: 1

0xF1
0xF1

Reputation: 6116

You should use the ternary operator like this:

server == 1 ? printf("%d %d", setA[i], setB[i]):printf("%d %d", setB[i], setA[i]);

and similarly for second statement.

The way you use it:

if server == 1
then setA[i], setB[i] evaluates to setB[i], because that is property of comma , operator in C, and only the last statement is executed.

i.e.

If server == 1
then

printf("%d %d\n",server==1?setA[i],setB[i]:setB[i],setA[i]);

will be evaluated as (due to high precedence of ?: operator over , operator)

printf("%d %d\n",(server==1?(setA[i],setB[i]):setB[i]),setA[i]);

which is

printf("%d %d\n",setB[i], setA[i]);

and similarly

printf("%d %d\n",server==0?setA[i],setB[i]:setB[i],setA[i]);

will be evaluated simply as

printf("%d %d\n",(server==0?(setA[i],setB[i]):setB[i]),setA[i])

which is again

printf("%d %d\n",setB[i],setA[i]);

You can parse similarly for server == 0 you will get same result.

Upvotes: 0

Yu Hao
Yu Hao

Reputation: 122383

server==1?setA[i],setB[i]:setB[i],setA[i]

Note the comma operator between the conditional operator, this expression doesn't result as you expected.

Instead, I suggest using an if statement. It's more clear and less error-prone.

if (server == 1)
{
    printf("%d %d\n", setA[i], setB[i]);
}
else
{
    printf("%d %d\n", setB[i], setA[i]);
}

Upvotes: 1

Related Questions