Velocity Reviews > Conditional operator problem

# Conditional operator problem

Mahesh Tomar
Guest
Posts: n/a

 07-21-2003
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.

Mahesh

Arthur J. O'Dwyer
Guest
Posts: n/a

 07-21-2003

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

Eric Sosman
Guest
Posts: n/a

 07-21-2003
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.

--
http://www.velocityreviews.com/forums/(E-Mail Removed)

Kevin Easton
Guest
Posts: n/a

 07-21-2003
Eric Bernard <(E-Mail Removed)> wrote:
[please don't top-post in technical newsgroups]
> "Mahesh Tomar" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed) om...
>> 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.

Eric Bernard
Guest
Posts: n/a

 07-22-2003

"Kevin Easton" <(E-Mail Removed)> wrote in message
news:newscache\$aeeeih\$6bn\$(E-Mail Removed)...
> Eric Bernard <(E-Mail Removed)> wrote:
> [please don't top-post in technical newsgroups]
> > "Mahesh Tomar" <(E-Mail Removed)> wrote in message
> > news:(E-Mail Removed) om...
> >> 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.

Richard Bos
Guest
Posts: n/a

 07-22-2003
Eric Sosman <(E-Mail Removed)> 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

Eric Sosman
Guest
Posts: n/a

 07-22-2003
Richard Bos wrote:
>
> Eric Sosman <(E-Mail Removed)> 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'.

--
(E-Mail Removed)