Conditional operator problem

Discussion in 'C Programming' started by Mahesh Tomar, Jul 21, 2003.

  1. Mahesh Tomar

    Mahesh Tomar Guest

    Please see the code below :-

    void func()
    {
    unsigned char x,y,z=1;
    (z==1) ? (x) : (y) = 1; /* Compiles OK */
    ((z==1) ? (x) : (y)) = 1; /* Compiler generates an error "Variable
    expected" */
    }

    Its just an example, I'd mentioned above. I am wondering why does
    putting a parenthesis around the second expression is erreneous. I
    tried above peice of code with three different compiler, one of the
    compiler GCC 2.96 compiles it ok. However an older version of GCC and
    Microsoft VC++ compilers generate an error "variable expected". I'd
    like to know, are such assignment(s) allowed ? If yes, why the first
    assignment compiles ok whereas second one fails.

    Thanks in advance.

    Mahesh
     
    Mahesh Tomar, Jul 21, 2003
    #1
    1. Advertising

  2. On Mon, 21 Jul 2003, Mahesh Tomar wrote:
    >
    > void func()
    > {
    > unsigned char x,y,z=1;
    > (z==1) ? (x) : (y) = 1; /* Compiles OK */


    Right. If z==1, then x is evaluated and its value discarded.
    If z!=1, then 1 is assigned to y.

    > ((z==1) ? (x) : (y)) = 1; /* Compiler generates an error "Variable
    > expected" */


    Right. If z==1, then x is evaluated.
    If z!=1, then y is evaluated.
    Then you have an '= 1' tacked onto the end. To what does
    this assign? It can't assign to the value of x, or the value
    of y; that's just as silly as writing

    -x = 1; /* Assign to the value of -x ? */

    The result of the ?: operator is no more an lvalue than the result
    of the - operator, or the = operator itself.

    > Its just an example, I'd mentioned above. I am wondering why does
    > putting a parenthesis around the second expression is erreneous.


    For the same reason that putting parentheses around the (1,2) in
    the following expression is "erroneous":

    atan2(1,2) -- OK
    atan2((1,2)) -- invalid; only one argument to atan2()

    You're adding random parentheses in an attempt to make C do something
    that it can't.

    > I
    > tried above peice of code with three different compiler, one of the
    > compiler GCC 2.96 compiles it ok. However an older version of GCC and
    > Microsoft VC++ compilers generate an error "variable expected". I'd
    > like to know, are such assignment(s) allowed ?


    The result of ?: is *not* an lvalue, and thus can't be assigned to.
    The first statement doesn't do what you think it does.

    -Arthur
     
    Arthur J. O'Dwyer, Jul 21, 2003
    #2
    1. Advertising

  3. Mahesh Tomar

    Eric Sosman Guest

    Mahesh Tomar wrote:
    >
    > Please see the code below :-
    >
    > void func()
    > {
    > unsigned char x,y,z=1;
    > (z==1) ? (x) : (y) = 1; /* Compiles OK */
    > ((z==1) ? (x) : (y)) = 1; /* Compiler generates an error "Variable
    > expected" */
    > }
    >
    > Its just an example, I'd mentioned above. I am wondering why does
    > putting a parenthesis around the second expression is erreneous. I
    > tried above peice of code with three different compiler, one of the
    > compiler GCC 2.96 compiles it ok. However an older version of GCC and
    > Microsoft VC++ compilers generate an error "variable expected". I'd
    > like to know, are such assignment(s) allowed ? If yes, why the first
    > assignment compiles ok whereas second one fails.


    Both lines are erroneous. If either compiles without
    a diagnostic[*], the compiler is faulty.

    [*] Strictly speaking, the compiler is not required to
    issue a separate diagnostic for each line. However, most
    will attempt to do so.

    --
     
    Eric Sosman, Jul 21, 2003
    #3
  4. Mahesh Tomar

    Kevin Easton Guest

    Eric Bernard <> wrote:
    [please don't top-post in technical newsgroups]
    > "Mahesh Tomar" <> wrote in message
    > news:...
    >> Please see the code below :-
    >>
    >> void func()
    >> {
    >> unsigned char x,y,z=1;
    >> (z==1) ? (x) : (y) = 1; /* Compiles OK */
    >> ((z==1) ? (x) : (y)) = 1; /* Compiler generates an error "Variable
    >> expected" */
    >> }
    >>

    [...]
    > The ?: operator returns a right-value.


    This is true.

    > You cannot use it to choose which variable to assign to.


    This is not true - for example, we can rewrite the OPs code:

    void func()
    {
    unsigned char x, y, z = 1;
    *((z == 1) ? &x : &y) = 1;
    }

    - Kevin.
     
    Kevin Easton, Jul 22, 2003
    #4
  5. Mahesh Tomar

    Eric Bernard Guest

    "Kevin Easton" <> wrote in message
    news:newscache$aeeeih$6bn$...
    > Eric Bernard <> wrote:
    > [please don't top-post in technical newsgroups]
    > > "Mahesh Tomar" <> wrote in message
    > > news:...
    > >> Please see the code below :-
    > >>
    > >> void func()
    > >> {
    > >> unsigned char x,y,z=1;
    > >> (z==1) ? (x) : (y) = 1; /* Compiles OK */
    > >> ((z==1) ? (x) : (y)) = 1; /* Compiler generates an error "Variable
    > >> expected" */
    > >> }
    > >>

    > [...]
    > > The ?: operator returns a right-value.

    >
    > This is true.
    >
    > > You cannot use it to choose which variable to assign to.

    >
    > This is not true - for example, we can rewrite the OPs code:
    >
    > void func()
    > {
    > unsigned char x, y, z = 1;
    > *((z == 1) ? &x : &y) = 1;
    > }
    >
    > - Kevin.
    >


    Right, you *can* do that, but would you?
    A simple if(z==1) x=1; else y=1; looks a bit nicer. At least to me.
     
    Eric Bernard, Jul 22, 2003
    #5
  6. Mahesh Tomar

    Richard Bos Guest

    Eric Sosman <> wrote:

    > Mahesh Tomar wrote:
    > >
    > > Please see the code below :-
    > >
    > > void func()
    > > {
    > > unsigned char x,y,z=1;
    > > (z==1) ? (x) : (y) = 1; /* Compiles OK */
    > > ((z==1) ? (x) : (y)) = 1; /* Compiler generates an error "Variable
    > > expected" */
    > > }

    >
    > Both lines are erroneous. If either compiles without
    > a diagnostic[*], the compiler is faulty.


    What's wrong with the first line? Yes, it invokes undefined behaviour
    because x is uninitialised, but imprimis that's a fault in the whole
    function, not that one line, and secundis diagnostics are not required
    for UB.

    Richard
     
    Richard Bos, Jul 22, 2003
    #6
  7. Mahesh Tomar

    Eric Sosman Guest

    Richard Bos wrote:
    >
    > Eric Sosman <> wrote:
    >
    > > Mahesh Tomar wrote:
    > > >
    > > > Please see the code below :-
    > > >
    > > > void func()
    > > > {
    > > > unsigned char x,y,z=1;
    > > > (z==1) ? (x) : (y) = 1; /* Compiles OK */
    > > > ((z==1) ? (x) : (y)) = 1; /* Compiler generates an error "Variable
    > > > expected" */
    > > > }

    > >
    > > Both lines are erroneous. If either compiles without
    > > a diagnostic[*], the compiler is faulty.

    >
    > What's wrong with the first line? [...]


    Unless I'm wrong (it's happened ...), both parse identically:
    the `?:' ternary operator "binds more tightly than" the `='
    assignment operator. Let's see if I can get there from the
    grammar:

    - (z==1) is recognized as the "logical-OR-expression"
    constituting the first operand of `?:'

    - (x) is recognized as the "expression" constituting
    the second operand

    - (y) is recognized as the "conditional-expression"
    constituting the third operand

    - ... so the whole business before the `=' is recognized
    as a "conditional-expression"

    - ... which isn't an lvalue, as required by the `='
    operator.

    FWIW, the two completely different compilers I tried it
    on both issue diagnostics for the line in question, although
    gcc accepts *both* lines when run without `-ansi'.

    --
     
    Eric Sosman, Jul 22, 2003
    #7
    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. Alec S.
    Replies:
    10
    Views:
    10,227
    Alec S.
    Apr 16, 2005
  2. Bill Davidson
    Replies:
    2
    Views:
    341
    Claudio Jolowicz
    Apr 21, 2004
  3. Richard Tierney

    Problem evaluating conditional operator

    Richard Tierney, Jul 27, 2004, in forum: C++
    Replies:
    3
    Views:
    361
    Richard Tierney
    Jul 27, 2004
  4. bnp
    Replies:
    30
    Views:
    855
    Ralmin
    May 25, 2004
  5. mux

    Quirk in Conditional Operator?:

    mux, Jun 15, 2004, in forum: C Programming
    Replies:
    4
    Views:
    391
    Murali
    Jun 15, 2004
Loading...

Share This Page