TARS
TARS

Reputation: 47

Error in assignment statement even when l-value given is fine in ternary operator

Consider the following C code.

#include <stdio.h>

int main(void)
{
  int test = 0;
  int a= 10,b = 20;
  test ? a*2 : b*3;
  printf("a = %d, b = %d\n",(test ? a = 200 : b = 300),(test ? a =2 : b = 3));

  return 0;
}

When trying to compile it throws the following error.

file1.c:11:50: error: lvalue required as left operand of assignment
printf("a = %d, b = %d\n",(test ? a = 200 : b = 300),(test ? a =2 : b = 3));
                                              ^
file1.c:11:74: error: lvalue required as left operand of assignment
printf("a = %d, b = %d\n",(test ? a = 200 : b = 300),(test ? a =2 : b = 3));
                                                                      ^

I have already provided an l value as left operand for the assignment operations and besides why does it not throw an error in the line

test ? a*2 : b*3;

and it produces error only in the line

printf("a = %d, b = %d\n",(test ? a = 200 : b = 300),(test ? a =2 : b = 3));

Please explain.

Upvotes: 1

Views: 252

Answers (2)

Dr. Essen
Dr. Essen

Reputation: 621

The ternary operator(?:) has higher precedence(not strictly) as compared to assignment(=). So, putting assignment statement inside round brackets can have more precedence as shown:

#include <stdio.h>

int main(void)
{
  int test = 0, ret;
  int a= 10,b = 20;
  test ? a*2 : b*3;
  printf("a = %d, b = %d\n",(test ? (a = 200) : (b = 300)), (test ? (a =2) : (b = 3)));

  return 0;
}

Strictly speaking, it's not the matter of Operator precedence, but of language grammar.

According to C Operator Precedence:

The C language standard doesn't specify operator precedence. It specifies the language grammar, and the precedence table is derived from it to simplify understanding. There is a part of the grammar that cannot be represented by a precedence table: an assignment-expression is not allowed as the right hand operand of a conditional operator, so e = a < d ? a++ : a = d is an expression that cannot be parsed, and therefore relative precedence of conditional and assignment operators cannot be described easily.

However, many C compilers use non-standard expression grammar where ?: is designated higher precedence than =, which parses that expression as e = ( ((a < d) ? (a++) : a) = d ), which then fails to compile due to semantic constraints: ?: is never lvalue and = requires a modifiable lvalue on the left. This is the table presented on this page.

Upvotes: 2

r3mus n0x
r3mus n0x

Reputation: 6144

You're probably missing parenthesis and the compiler thinks you mean:

(test ? a = 200 : b) = 300

when you actually meant:

test ? (a = 200) : (b = 300)

Upvotes: 2

Related Questions