Thread: ternary operator

  1. #1
    Registered User
    Join Date
    Jun 2006
    Posts
    12

    ternary operator

    Code:
    #include<stdio.h>
    
    int main()
    {
           int a=10,b=0;
           a<0?b=100:b=200;
           return 0;
    }

    hi everybody,

    The above code isnt compiling.. it says invalid lvalue
    i have no idea why the lvalue is getting altered here if ...
    it works only if i include b=200 with parenthesis.. ie., works if written this way

    Code:
    a<0?b=100:(b=200);

    i want to know how the compiler interprets the above statement..
    guess it is a precedence problem...


    regards
    Abhijith

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Try:
    Code:
    b = a < 0 ? 100 : 200;
    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by abhijith gopal
    i want to know how the compiler interprets the above statement..
    guess it is a precedence problem...
    C Language Operator Precedence Chart
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  4. #4
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Code:
    a<0?b=100:(b=200);
    First it evaluates b=200, which assignes the value of 200 to b and returns 200.
    Then it evaluates b=100, which assignes the value of 100 to b and returns 100.
    Then it evaluates a<0.
    Then it calls the ternary opperator which returns either 100 or 200. b remains the value of 100 however.

    The key things to remmember are 1) ternary opperator reads right to left, and 2) the assignment opperator is of lower precidence to the ternary opperator.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  5. #5
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by King Mir
    Code:
    a<0?b=100:(b=200);
    First it evaluates b=200, which assignes the value of 200 to b and returns 200.
    Then it evaluates b=100, which assignes the value of 100 to b and returns 100.
    Then it evaluates a<0.
    Then it calls the ternary opperator which returns either 100 or 200. b remains the value of 100 however.
    Not quite.
    6.5.15 Conditional operator

    Constraints

    2 The first operand shall have scalar type.
    3 One of the following shall hold for the second and third operands:
    — both operands have arithmetic type;
    — both operands have the same structure or union type;
    — both operands have void type;
    — both operands are pointers to qualified or unqualified versions of compatible types;
    — one operand is a pointer and the other is a null pointer constant; or
    — one operand is a pointer to an object or incomplete type and the other is a pointer to a
    qualified or unqualified version of void.

    Semantics

    4 The first operand is evaluated; there is a sequence point after its evaluation. The second operand is evaluated only if the first compares unequal to 0; the third operand is evaluated only if the first compares equal to 0; the result is the value of the second or third operand (whichever is evaluated), converted to the type described below.92) If an attempt is made to modify the result of a conditional operator or to access it after the next sequence point, the behavior is undefined.

    5 If both the second and third operands have arithmetic type, the result type that would be determined by the usual arithmetic conversions, were they applied to those two operands, is the type of the result. If both the operands have structure or union type, the result has that type. If both operands have void type, the result has void type.

    6 If both the second and third operands are pointers or one is a null pointer constant and the other is a pointer, the result type is a pointer to a type qualified with all the type qualifiers of the types pointed-to by both operands. Furthermore, if both operands are pointers to compatible types or to differently qualified versions of compatible types, the result type is a pointer to an appropriately qualified version of the composite type; if one operand is a null pointer constant, the result has the type of the other operand; otherwise, one operand is a pointer to void or a qualified version of void, in which case the result type is a pointer to an appropriately qualified version of void.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  6. #6
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    But how exactly does it work if you have nested conditional opperators?
    I mean conditionals are read right to left right?
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  7. #7
    Registered User
    Join Date
    Aug 2005
    Posts
    44
    The first operand is evaluated; there is a sequence point after its evaluation. The second operand is evaluated only if the first compares unequal to 0; the third operand is evaluated only if the first compares equal to 0; the result is the value of the second or third operand (whichever is evaluated)
    Sorry for dumb question, but Im lost on semantics here. Which is the first, second and third operand of a conditional operation?

  8. #8
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    first ? second : third
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  9. #9
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    result = first ? second : third


    Quzah.
    Hope is the first step on the road to disappointment.

  10. #10
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    So how are conditionals read right to left again?
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  11. #11
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Given
    Code:
    result = first ? second : third
    first is evaluated. If it's true, result is assigned the value of the expression second. Otherwise, result gets the value of expression third. Only one of second and third is evaluated, never both.

    [edit] The above is exactly the same as
    Code:
    if(first) result = second;
    else result = third;
    [/edit]
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    > So how are conditionals read right to left again?
    You're referring to associativity, which is used to resolve ambiguity when using operators of the same precedence.

    Eg.
    a + b - c
    a+b happens first, then c is subtracted from the result.

    More examples here, including a nested ?: expression.
    http://h30097.www3.hp.com/docs/base_...E/DOCU_059.HTM

    Not to be mixed up with evaluation order, which is unspecified
    http://www.c-faq.com/expr/precvsooe.html
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  13. #13
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Now I'm confused.

    So seemingly, the expression "a?b:c" gets evaluated in the order a then b or c, unless either b or c is a conditional expression.

    Code:
    f(int x)
    {
         return x;
    }
    
    f(0)?g():h()
    This calls f() then h() correct? Or does it call f(), g(), and h() in undefined order?

    In C++, what is the order of evaluation here? (I assume it's the same in C, but C++ allows overloaded opperators, so it's more confermable)
    Code:
    void e();
    void i();
    
    a+b?c-d?e():i():j*k?f():g()
    Quote Originally Posted by Salem
    Not to be mixed up with evaluation order, which is unspecified
    http://www.c-faq.com/expr/precvsooe.html
    f() + g() * h()
    If I may use C++ terms here,

    From what I understand though, while the order of the function calls is undefined, opperator* still must be evaluated before opperator+. So it's much like how the order of values passed to a function is undefined, the above expands to
    Code:
    opperator+(f(),opperator*(g(),h()))
    Last edited by King Mir; 07-09-2006 at 09:07 PM.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  14. #14
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Quote Originally Posted by King Mir
    This calls f() then h() correct? Or does it call f(), g(), and h() in undefined order?
    Read what Dave posted again. It's very clear. I don't see why you're having problems understanding it:
    Quote Originally Posted by Dave_Sinkula
    The first operand is evaluated ... The second operand is evaluated only if the first compares unequal to 0; the third operand is evaluated only if the first compares equal to 0;
    If the operand isn't evaulated, it's not processed. f() is called and then h() is called. g() is never called.
    If you understand what you're doing, you're not learning anything.

  15. #15
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    They don't all get called. Test it yourself. Why does no one write any test code? It's not hard.
    Code:
    #include<stdio.h>
    
    int a( int x ) { return putchar( 'a' ); }
    int b( int x ) { return putchar( 'b' ); }
    int c( int x ) { return putchar( 'c' ); }
    
    int main( void )
    {
        int x = 0;
        x = c( 0 ) ? a( x ) : b( x );
        return 0;
    }
    Besides, all you had to do is read the quoted text to find out that they wouldn't all get called. Hell it's hilighted for you even. So not only do you not write a simple test case, you don't even read.

    [edit]
    Curses, foiled again!
    [/edit]

    Quzah.
    Hope is the first step on the road to disappointment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Smart pointer class
    By Elysia in forum C++ Programming
    Replies: 63
    Last Post: 11-03-2007, 07:05 AM
  2. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  3. Operator Overloading (Bug, or error in code?)
    By QuietWhistler in forum C++ Programming
    Replies: 2
    Last Post: 01-25-2006, 08:38 AM
  4. operator overloading and dynamic memory program
    By jlmac2001 in forum C++ Programming
    Replies: 3
    Last Post: 04-06-2003, 11:51 PM
  5. ternary operator(?), vectors, and recursive function
    By kes103 in forum C++ Programming
    Replies: 2
    Last Post: 02-02-2003, 03:19 PM