1

While compiling the code below I'm getting the error "lvalue required as left operand of assignment"

for (i = 1; i < 2 n; i++) {
    for (((i<= n)?j=1:j=n-i);j<=i&&j>0;((i<=n)?j++:j--)) {
        printf("*");
    }
    printf("\n");
}

Actually I was trying to print the pattern below using only two for loops

*
**
***
****
*****
****
***
**
*

and the error I'm getting is

pra.c:5:20: error: lvalue required as left operand of assignment for(((i<=5)?j=1:j=i);j<=i&&j>0;((i<=5)?j++:j--)){ ^
could someone help me.

vmc7001
  • 41
  • 6
  • You should change `((i<=5)?j=1:j=i)` to `(j=((i<=5)?1:i))` – Awais Chishti Aug 15 '16 at 05:01
  • 1
    In C programming, you unfortunately don't get any bonus points for using every operator in the language on a single line... Write readable code instead. – Lundin Aug 15 '16 at 06:08

1 Answers1

5

In C language the grammar and the semantics of the conditional operator is different from C++. Your code would compile in C++, since in C++ the expression

<condition> ? a = b : c = d

would be parsed as

<condition> ? (a = b) : (c = d)

In C the same expression is parsed as

(<condition> ? (a = b) : c) = d

which is a completely different story. The result of ?: in C is never an lvalue, which is why the latter parsing does not compile.

Your code suffers from exactly the same error.

More pedantically, as Johannes noted in the comments, the ?: is not eligible to serve as the left-hand side of the assignment operator for reasons that have nothing to do with lvalues or rvalues. The grammar simply immediately disallows it. The expression is not supposed to be parsable at all. However, judging by the error message you quoted, your compiler sees the problem differently (or at least reports it in a way that can be seen as "mildly misleading").

This is one of the rather well-known differences between C and C++ languages:

Errors using ternary operator in c

Conditional operator differences between C and C++

Community
  • 1
  • 1
AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • At the time of my writing this, this answer is the only correct one. – Bathsheba Aug 15 '16 at 06:55
  • I always tend to forget this. I thought the left hand side of assignment in C is "unary-expression". How can it fit a conditional-expession there then? – Johannes Schaub - litb Aug 15 '16 at 06:57
  • Can you please give a derivation of ` ? a = b : c = d` as an assignment-expression in C? I can't see it yet, since ` ? a = b : c` is not an unary-expression at all. Why would they make it a non-lvalue expression grammatically on purpose? I think this expression simply is syntactically wrong, there is no parse of it either way in C. – Johannes Schaub - litb Aug 15 '16 at 07:04
  • @Johannes Schaub - litb: Where do you see the problem exactly? The language grammar says that `conditional-expression` is `logical-OR-expression` or `logical-OR-expression ? expression : conditional-expression`. The second operand is `expression`, which can involve assignment operator. The third operand is `logical-OR-expression`, which (if you trace the whole tree) boild down to `unary-expression` and cannot include assignment operator. So, the trailing assignment is left outside of the `?:`. – AnT stands with Russia Aug 15 '16 at 07:20
  • As for it being a non-lvalue... That's just one of the fundamental properties of C (again, different from C++). Overwhelming majority of expressions in C produce rvalues, rvalues and rvalues. The only things that are lvalues in C are basically direct variable name and the result of unary `*`. – AnT stands with Russia Aug 15 '16 at 07:22
  • right (the trailing tokens are left outside). But the whole sequence is not an assignment-expression, because an assignment expression starts with "unary-expression". And an unary-expression is not a conditional-expression. – Johannes Schaub - litb Aug 15 '16 at 07:23
  • Oh, you mean that once the trailing `=` is pushed outside, the whole thing should just fail with a syntax error, never getting to the point where it even begins to tell lvaluea from rvaluea... You are right, I guess. Apparently this compiler just issues a misleading error message. – AnT stands with Russia Aug 15 '16 at 07:25
  • Yes, there is no way that ` = ...` can be reduced further. I think the error message is spot-on for non-lawyers. There wasn't an lvalue expression given (which requires an unary-expression as far as I can see). – Johannes Schaub - litb Aug 15 '16 at 07:26