?: ternary conditional operator behaviour when leaving one expression empty

20,426

Solution 1

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.

Solution 2

This is a GCC extension to the C language. When nothing appears between ?:, then the value of the comparison is used in the true case.

The middle operand in a conditional expression may be omitted. Then if the first operand is nonzero, its value is the value of the conditional expression.

Therefore, the expression

    x ? : y

has the value of x if that is nonzero; otherwise, the value of y.

This example is perfectly equivalent to

    x ? x : y

In this simple case, the ability to omit the middle operand is not especially useful. When it becomes useful is when the first operand does, or may (if it is a macro argument), contain a side effect. Then repeating the operand in the middle would perform the side effect twice. Omitting the middle operand uses the value already computed without the undesirable effects of recomputing it.

Share:
20,426

Related videos on Youtube

TooBored
Author by

TooBored

Updated on August 05, 2020

Comments

  • TooBored
    TooBored almost 4 years

    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?

    • Justin Garrick
      Justin Garrick almost 14 years
      This type of conditional is called a ternary operation. You might get a better response if you re-tag or re-title your post to include 'ternary'.
    • ULysses
      ULysses almost 14 years
      <a href="en.wikipedia.org/wiki/%3F:">This</a> link, C Variants section
    • JeremyP
      JeremyP almost 14 years
      @Segphault: it is called the conditional operator (in C). It is an example of a ternary operator which is a generic term meaning any operator with three operands.
    • Lumen
      Lumen almost 14 years
      If YOU have doubts, which lead to this question, there is no doubt you should have made the true-case assignment explicit. TooBored.... Consider not coding dumb console games, 'cause it's a positive boredom feedbacker.
    • Keith Thompson
      Keith Thompson almost 8 years
      @JeremyP: Yes, "ternary operator" is a generic term for an operator with three operands. But the "conditional operator" (?:) happens to be the only ternary operator in C (and in many similar languages), so it's commonly called "the ternary operator". The usage is perhaps a bit sloppy, but common. (The C standard never refers to ?: as a "ternary" operator. In fact it uses the phrase "ternary operator" only when discussing the semantics of the fma() function, which computes (x × y) + z.)
  • kennytm
    kennytm almost 14 years
    Almost equivalent ... except x is evaluated only once in x ?: y.
  • Stephen
    Stephen almost 14 years
    @KennyTM: True, I should explicitly state that.
  • Ted
    Ted over 8 years
    I tried this ternary syntax with missing second operand on xlc (IBM XL C/C++ for AIX, V11.1) and it also worked.
  • rudimeier
    rudimeier over 7 years
    I know some projects which seem to be tested highly portable although using "?:". Any example of a non-working compiler?
  • Lars Nyström
    Lars Nyström over 4 years
    Hah, "perfectly equivalent". Of course everything is perfectly equivalent if you ignore the differences...
  • mbauman
    mbauman over 4 years
    It really is perfectly equivalent in that simple case.
  • 4LegsDrivenCat
    4LegsDrivenCat over 2 years
    It works for Clang too, not only GCC.