Quirk in Conditional Operator?:

Discussion in 'C Programming' started by mux, Jun 15, 2004.

  1. mux

    mux Guest

    Hi

    I found out that the following piece of code throws an error.

    1 #include "stdio.h"
    2
    3 int main()
    4 {
    5 int a,b;
    6 a= 10;
    7 a>10?b=20:b=30;
    8 printf("%d",b);
    9 }

    and the error was:
    $ gcc -g -o test test.c
    test.c: In function `main':
    test.c:7: error: invalid lvalue in assignment

    However, when you rewrite line 7 as:

    a>10?b=20:(b=30);

    Then there is no error. Why it is so? I thought conditional operators where
    an macro-like replacement of a simple if-else statement.

    Is there any other such odd things (not behavior) in using a conditional
    operator I need to be aware of?

    For that matter, is there any website that would point to such quirks in c?

    Any help would be greatly appreciated.

    Regards,
    Muralidhar
     
    mux, Jun 15, 2004
    #1
    1. Advertising

  2. "mux" <> wrote in
    news:candlq$n8g$-state.edu:

    > Hi
    >
    > I found out that the following piece of code throws an error.
    >
    > 1 #include "stdio.h"
    > 2
    > 3 int main()
    > 4 {
    > 5 int a,b;
    > 6 a= 10;
    > 7 a>10?b=20:b=30;
    > 8 printf("%d",b);
    > 9 }
    >
    > and the error was:
    > $ gcc -g -o test test.c
    > test.c: In function `main':
    > test.c:7: error: invalid lvalue in assignment
    >
    > However, when you rewrite line 7 as:
    >
    > a>10?b=20:(b=30);


    What happens when you write it for clarity? E.g.

    b = a > 10 ? 20 : 30;

    Try that. If you are a parenaphile try:

    b = (a > 10) ? 20 : 30;

    --
    - Mark ->
    --
     
    Mark A. Odell, Jun 15, 2004
    #2
    1. Advertising

  3. mux <> scribbled the following:
    > Hi


    > I found out that the following piece of code throws an error.


    > 1 #include "stdio.h"
    > 2
    > 3 int main()
    > 4 {
    > 5 int a,b;
    > 6 a= 10;
    > 7 a>10?b=20:b=30;
    > 8 printf("%d",b);
    > 9 }


    > and the error was:
    > $ gcc -g -o test test.c
    > test.c: In function `main':
    > test.c:7: error: invalid lvalue in assignment


    > However, when you rewrite line 7 as:


    > a>10?b=20:(b=30);


    > Then there is no error. Why it is so? I thought conditional operators where
    > an macro-like replacement of a simple if-else statement.


    They're nothing of the sort. The conditional operator is a real, kosher,
    all-singing, all-dancing C operator with C semantics. Thus, it must obey
    C rules about operator precedence and lvalues.
    In an assignment operation, the RHS must be a modifiable lvalue, and I
    don't think the conditional operator produces such things. If I know my
    precedence rules, what you are doing is equivalent to:
    (a>10 ? (b=20) : b) = 30;
    which won't work. However I think you meant:
    (a>10) ? (b=20) : (b=30);

    Note that you can't do this:
    (a<10 ? a : b) = 30;
    but you can do this:
    *(a<10 ? &a : &b) = 30;
    because the unary * (indirect through) operator turns rvalues of type
    "pointer-to-T" into modifiable lvalues of type "T".

    --
    /-- Joona Palaste () ------------- Finland --------\
    \-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
    "The day Microsoft makes something that doesn't suck is probably the day they
    start making vacuum cleaners."
    - Ernst Jan Plugge
     
    Joona I Palaste, Jun 15, 2004
    #3
  4. mux

    Eric Sosman Guest

    mux wrote:
    > Hi
    >
    > I found out that the following piece of code throws an error.
    >
    > 1 #include "stdio.h"
    > 2
    > 3 int main()
    > 4 {
    > 5 int a,b;
    > 6 a= 10;
    > 7 a>10?b=20:b=30;
    > 8 printf("%d",b);
    > 9 }
    >
    > and the error was:
    > $ gcc -g -o test test.c
    > test.c: In function `main':
    > test.c:7: error: invalid lvalue in assignment
    >
    > However, when you rewrite line 7 as:
    >
    > a>10?b=20:(b=30);
    >
    > Then there is no error. Why it is so? I thought conditional operators where
    > an macro-like replacement of a simple if-else statement.


    Informally speaking, the conditional operator `?:' has
    "higher precedence than" or "binds more tightly than" the
    assignment operator `='. (More formally, the Standard that
    defines the C language specifies a grammar for the language,
    and the grouping of operators with operands is a consequence
    of the way the grammar is defined. Usually it's easier to
    use terms like "precedence" when talking to humans rather
    than to parsers.)

    Of course, saying that one operator has higher precedence
    than another "because it's defined that way" merely avoids
    the issue: *Why* is the language defined this way? The answer
    is that the inventors chose rules that would lead to "natural-
    looking" expressions in the most common cases. The multiplication
    operator `*' has higher precedence than the subtraction operator
    `-' because people expect `a*b-c' to mean `(a*b)-c' rather than
    `a*(b-c)'. The assignment operator `=' has a very low precedence
    because people expect `x=a+b' to mean `x=(a+b)' and not `(x=a)+b'.

    So: The assignment operator has very low precedence; it
    "binds less tightly" than almost all other operators. Your
    original statement is therefore understood as

    ((a>10)?(b=20):b)=30;

    .... and now, I suppose, you can understand gcc's complaint:
    the thing on the left-hand side of the assignment operator
    is not something one can assign to. It's analogous to writing
    `x+1=b'.

    When you repair the expression by inserting explicit
    parentheses, the result is parsed as

    (a>10)?(b=20):(b=30);

    .... which makes sense. You may be wondering why the middle
    set of parentheses wasn't actually required: I've just been
    telling you that the assignment in `b=20' has lower precedence
    than the conditional operator, which might lead you to think
    that your final version would be parsed as

    ((a>10)?b)=20:(b=30);

    .... which is complete nonsense. Well, that's where notions
    like "precedence" are too simplistic for a good explanation.
    The Standard's grammar is constructed in such a way that this
    nonsensical parse is not attempted; the "inner" assignment is
    "known" to occur in a context where it must "bind more tightly"
    than the `?:'. No such simple escape is possible for the
    third sub-expression, though: we're back into "open context."

    By the way, the usual form for your statement is something
    more like

    b = a>10 ? 20 : 30;

    .... which once again exhibits the desirability of "low precedence"
    for the assignment operator.

    > Is there any other such odd things (not behavior) in using a conditional
    > operator I need to be aware of?


    I don't know how to answer this, because something that
    seems odd to you may seem perfectly normal to me or to anyone
    with greater experience of the language. "Oddity is in they
    eye of the beholder."

    > For that matter, is there any website that would point to such quirks in c?


    Every web site and every text or reference work on any
    subject at all probably contains something that someone would
    consider a "quirk." If you can give a rigorous definition of
    "quirk" there might be a way to answer the question -- but if
    you could give such a definition, you'd probably no longer need
    to have the question answered!

    --
     
    Eric Sosman, Jun 15, 2004
    #4
  5. mux

    Murali Guest

    Wow...That was one of the most elegant answer I have seen in years.

    Thanks for helping me out. and true that Quirk is in the eyes of the
    beholder. But I felt that someone might be gracious enough to put a warning
    sign for such tiny titbits that would life of a programmer(and a debugger)
    much easier.

    Thanks once again

    Regards
    Muralidhar
     
    Murali, Jun 15, 2004
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Chris Morris

    Re: dtd and quirk mode

    Chris Morris, Jul 22, 2003, in forum: HTML
    Replies:
    0
    Views:
    408
    Chris Morris
    Jul 22, 2003
  2. Richard
    Replies:
    1
    Views:
    422
  3. Blinky the Shark

    Konqueror Quirk? Safari?

    Blinky the Shark, Feb 18, 2004, in forum: HTML
    Replies:
    9
    Views:
    462
    Blinky the Shark
    Feb 20, 2004
  4. Spartanicus

    IE6 quirk check

    Spartanicus, Jul 16, 2004, in forum: HTML
    Replies:
    2
    Views:
    457
    Spartanicus
    Jul 16, 2004
  5. Alec S.
    Replies:
    10
    Views:
    10,329
    Alec S.
    Apr 16, 2005
Loading...

Share This Page