13

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.

Yugal Jindle
  • 44,057
  • 43
  • 129
  • 197

4 Answers4

21

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.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
Nawaz
  • 353,942
  • 115
  • 666
  • 851
9

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;
Scott Logan
  • 1,518
  • 2
  • 17
  • 34
  • 2
    -1, not true. See the wikipedia explanation at http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Notes – Johannes Schaub - litb Aug 06 '11 at 11:17
  • 1
    I'm sorry I don't see it, they show `e = a < d ? a++ : a = d` being parsed like `e = ((a < d ? a++ : a) = d)` which appears to be similiar to what I have written. Do you mean the part where it says it shouldn't be parsed? – Scott Logan Aug 06 '11 at 11:25
2

It is really:

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

Note: you should simply

b = (a>b)?a:b;
Karoly Horvath
  • 94,607
  • 11
  • 117
  • 176
0

When we put an equation in parenthesis it is treated as an expression. And it returns some value which provide solution to the error.

Sanchit Paurush
  • 6,114
  • 17
  • 68
  • 107