Conditional operator problem

M

Mahesh Tomar

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
 
A

Arthur J. O'Dwyer

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
 
E

Eric Sosman

Mahesh said:
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.
 
K

Kevin Easton

Eric Bernard said:
Mahesh Tomar said:
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.
 
E

Eric Bernard

Kevin Easton said:
Eric Bernard said:
Mahesh Tomar said:
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.
 
R

Richard Bos

Eric Sosman said:
Mahesh said:
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
 
E

Eric Sosman

Richard said:
Eric Sosman said:
Mahesh said:
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'.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top