Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error: lvalue required in this simple C code? (Ternary with assignment?)

I have :

#include<stdio.h>

int main()
{
 int a=5,b=6;
 (a>b)?b=a:b=b;    // Here is the error
 return 0;
}

But if I replace :

(a>b)?b=a:b=b;       // Error
with   
(a>b)?(b=a):(b=b);   // No-Error

I understand the lvalue is a value to which something can be assigned and how is it different from rvalue, but why is the extra parenthesis making the difference.

like image 810
Yugal Jindle Avatar asked Aug 06 '11 10:08

Yugal Jindle


People also ask

What is the error lvalue required in C?

This error occurs when we put constants on left hand side of = operator and variables on right hand side of it.

Does the ternary operator return lvalue?

Ternary conditional operator will yield an lvalue, if the type of its second and third operands is an lvalue.

What is lvalue expected in C?

An assignment expects an lvalue as its left operand, and var is an lvalue, because it is an object with an identifiable memory location. On the other hand, the following are invalid: 4 = var; // ERROR!


2 Answers

Actually, in C, this code

(a>b)?b=a:b=b; 

is parsed by many compilers as

((a>b)?b=a:b)=b;

which is an error, as the expression ((a>b)?b=a:b) evaluates to an rvalue which you try to assign with b which results in an error. Trying to assign an rvalue is an error. If it is not parsed that way, then its simply a syntax error. But a C compiler is NOT allowed to parse it as:

((a>b)?b=a:(b=b)); //not allowed to parse by C language

Because the grammar of C does not allow a compiler to parse the code as above.

But what you've written (the original code) is correct as C++.

Here the grammars of C and C++ differ a lot. And because of that difference you see both languages treat the expression differently. That is, the conditional expression in C++ is different from the conditional expression in C .

Wikipedia has very good and correct explanation for this:

The binding of operators in C and C++ is specified (in the corresponding Standards) by a factored language grammar, rather than a precedence table. This creates some subtle conflicts. For example, in C, the syntax for a conditional expression is:

logical-OR-expression ? expression : conditional-expression

while in C++ it is:

logical-OR-expression ? expression : assignment-expression

Hence, the expression:

e = a < d ? a++ : a = d

is parsed differently in the two languages. In C, this expression is a syntax error, but many compilers parse it as:

e = ((a < d ? a++ : a) = d)

which is a semantic error, since the result of the conditional-expression (which might be a++) is not an lvalue. In C++, it is parsed as:

e = (a < d ? a++ : (a = d))

which is a valid expression.

like image 173
Nawaz Avatar answered Oct 19 '22 17:10

Nawaz


Assignment has a lower precedence than the ternary operator so the line evaluates like:

((a>b)?b=a:b)=b;

use:

b=(a>b)?a:b;
like image 36
Scott Logan Avatar answered Oct 19 '22 15:10

Scott Logan