Getting error "lvalue required as left operand of assignment" - c

I am a novice in C and having the following problem while compiling a simple code:
#include <stdio.h>
int main()
{
int i, a, b;
i = 3;
a = b = 0;
printf("Before: ");
printf("%d %d\n", a, b);
i == 3 ? a = 4 : a = 10; /* Line 9 */
printf("After: ");
printf("%d %d\n", a, b);
return 0;
}
Gives me error:
#gcc some.c
In function ‘main’:
some.c:9: error: lvalue required as left operand of assignment
I cannot understand it. What am i doing wrong?

This operator
i==3 ? a=4 : a = 10;
is equivalent to
( i==3 ? a=4 : a ) = 10;
Use instead
i==3 ? a=4 : ( a = 10 );

You need to assign outside the ternary operator, not inside of it, because the ternary operator binds tighter than assignment. So you should write
a = ((i == 3) ? 4 : 10);
What you wrote is equal to
(i == 3 ? a = 4 : a ) = 10;
In this code, an rvalue is being assigned to. This is the same error as writing
myfunc() = 16;
Cosmetic note: In this case it is better to use an if else statement instead of a conditional operator, because it is more clear here.
if (i == 3)
a = 4;
else
a = 10;

?: is a ternary operator.
ternary operator have higher precedence than '=' operator.
so 9th line of your code work like this..
(i == 3 ? a = 4 : a) = 10;
you have to use parenthesis or modify your sentence.
you can replace your 9th line with either of following line..
i == 3 ? a = 4 : (a = 10);
a = i == 3 ? 4 : 10;

a = (i == 3 ? 4 : 10);
Try this! :-)

Try this
if (i==3) a = 4; else a = 10;

The ternary operator does not work like this. You should use parenthesis to give higher priority to the equality operator. Check the priority precedence. By default, equality operators have least priority.

Related

I'm trying to use conditional expression ?: in C but keep getting errors

I'm trying to use conditional expression, ?:, in C but keep getting the error:
expression must be a modifiable lvalue" and "'=': left operand must be
l-value".
What did I do wrong?
#include <stdio.h>
#include <stdlib.h>
#pragma warning (disable : 4996)
void main(void) {
int a = 1;
char x;
a == 1 ? x = 't' : x = 'f';
putchar(x);
system("pause");
}
The condition operator ?: has higher precedence than the assignment operator =. So this:
a == 1 ? x = 't' : x = 'f';
Parses as this:
(a == 1 ? x = 't' : x) = 'f';
And the result of the ternary operator is not an lvalue (i.e. it can't appear on the left side of an assignment) so it's invalid.
You can use parenthesis to get the grouping you want:
(a == 1) ? (x = 't') : (x = 'f');
But since you're using this operator to assign a value to x, the proper way to use it would be:
x = a == 1 ? 't' : 'f';

Is it possible to reduce an if_else statement to a single line code

I wonder if I can reduce the number of lines of the following code to a single one?
if (a > (b+10))
{
value = 1;
}
else
{
value = 0;
}
For booleans (true, false) just do:
bool value = a > b + 10;
You could use the ternary operator:
value = (a > (b+10)) ? 1 : 0;
For this case there are two options:
ternary operator
using the boolean value
Ternary operator
The ternary operator can substitute very simple if-else conditions such as:
value = (a > (b+10)) ? 1 : 0;
Boolean value
Since your condition is attributing the value of 1 or 0 you can simply use the condition evalution. In c when you evaluate a condition it returns an integer between 1 and 0. Which is exactly your objective, making the above expression even simpler.
value = (a > (b+10))
Yes, using ternary operator.
Syntax:
var = (condition) ? (expression1 if condition is true) : (expression2 if condition is false);
Your example:
value = (a > (b+10)) ? 1 : 0;
Reducing the number of lines is easy: you can use a different brace style:
if (a > (b+10)) {
value = 1;
} else {
value = 0;
}
You can use single statements instead of blocks:
if (a > (b+10))
value = 1;
else
value = 0;
You can cram the if statement on a single line (with or without curly braces):
if (a > (b+10)) { value = 1; } else { value = 0; }
if (a > (b+10)) value = 1; else value = 0;
You can further simplify using the ternary operator:
value = (a > (b+10)) ? 1 : 0;
You can also remove redundant parentheses:
value = a > b + 10 ? 1 : 0;
Finally, since comparisons in C evaluate to int values 1 or 0, the above expression is still fully redundant, so you could simply write:
value = a > b + 10;
Note that value does not need to have type bool for its value to be 1 or 0 in this case, but typing it as bool may help the reader better understand the code.

What does a : mark in C mean?

void main()
{
int x,y;
scanf("%d", &x); <-1
y=(x>5?3:4);
printf("%d",y); ->4
}
What is the use of: in y=(x>5?3:4); ?
It is known as ternary operator. This:
y= (x>5 ? 3 : 4);
means if x is greater than 5, to y will be assigned the value 3, otherwise (x is less or equal to 5) the value 4 will be assigned to y. That code is semantically the same as:
if(x > 5)
y = 3;
else
y = 4;
you can find a more in-depth explanation here.
"What is the use of : in y=(x>5?3:4); ?"
: represents the shorthand version of the else clause of an if-then-else expression when using the C ternary operator. So in your example:
y = (x>5 ? 3 : 4);
The English expression could be stated as:
if x is greater than 5, then set y equal to 3, else set
y equal to 4.
The traditional long version in C syntax would use the expression sequence:
if(x > 5)
{
//true path
y = 3;
}
else
{
//false path
y = 4;
}
It's a ternary operator or conditional operator.

C expression must be a modifiable lvalue (Why am i getting on this expression)

I have this expression with ?: operator:
(adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1)) > 10 ? Counter.WriteOut = 1 : Counter.WriteOut = 0;
And the same expression with if-else:
if((adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1)) > 10 ){
Counter.WriteOut = 1;
}else{
Counter.WriteOut = 0;
}
Why am I getting "expression must be a modifiable lvalue" error in the first case?
The ADC_readResult function return type is uint_least16_t. Here is the Counter struct definition and the ADC struct definition:
typedef struct __COUNTERS__ {
uint16_t WriteOut;
uint16_t ADC_ConversionCount;
uint16_t ADC_CycleCount;
uint8_t LimitADCReached1;
uint8_t LimitADCReached2;
uint8_t LimitADCReached3;
uint8_t LimitADCReached4;
uint8_t LimitADCReached5;
} COUNTERS;
typedef struct __ADC_VOLTAGES__ {
uint16_t Voltage1[ADC_VAL];
uint16_t Voltage2[ADC_VAL];
uint16_t Voltage3[ADC_VAL];
uint16_t Voltage4[ADC_VAL];
uint16_t Voltage5[ADC_VAL];
} ADC;
The error you're getting has to do with the way the expression is parsed.
Your expression (simplified) looks like this:
(a = b) < 10 ? c = 1 : c = 0
The ternary operator ?: has higher precedence than the assignment operator =. While the inner = is seen as part of the ternary, the rightmost one is not. So the expression parses like this:
((a = b) < 10 ? c = 1 : c) = 0;
The result is that you're trying to assign the value 0 to an expression that is not an lvalue, i.e. a variable name or a dereferenced pointer. You would need parenthesis for it to parse the way you want:
((a = b) < 10) ? (c = 1) : (c = 0);
Since what you're doing is assigning a value to c based on an expression, it can be simplified as follows:
c = ((a = b) < 10) ? 1 : 0;
Or even:
c = ((a = b) < 10);
Translating back to your code:
Counter.WriteOut = (adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1) > 10);
And made more readable by splitting the operations:
adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1);
Counter.WriteOut = (adc.Voltage1[Counter.ADC_ConversionCount] > 10);
I think it should be:
Counter.WriteOut = (adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1)) > 10 ? 1 : 0;
The ?: operator has higher precedence than = operator, so the first expression is interpreted as
(
(adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1)) > 10 ?
Counter.WriteOut = 1 : Counter.WriteOut
) = 0
Therefore, the lefthand expression of = is not modifiable.
Use parenthesis to avoid this:
(adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1)) > 10 ? Counter.WriteOut = 1 : (Counter.WriteOut = 0);
(no parenthesis are needed for Counter.WriteOut = 1 because it is middle of ?: operator and no ambiguity is there)
Because what is assigned are common Counter.WriteOut, I prefer
Coumter.WriteOut = ((adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1)) > 10 ? 1 : 0);
or, using definition of comparision operators of C (it returns 1 for true and 0 for false),
Coumter.WriteOut = ((adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1)) > 10);

C programme error "left operand of assignment"

Can anyone explain me why this line of code is wrong?
int n = 0, y = 1;
y == 1 ? n = 0 : n = 1;
The error is "Lvalue required as left operand of assignment " for "n=1"
The statement
(y == 1 ? n = 0 : n) = 1;
is interpreted as because n binds with ?: operator due to its higher precedence.
= needs l-value as its left operand while ?: returns an r-value.
Try this instead
y == 1 ? n = 0 : (n = 1);
or
n = y == 1 ? 0 : 1;
You should use :
n = y==1 ? 0 :1
According to the C standard, the behaviour is undefined if an attempt is made to use the result of the conditional operator as an Lvalue.
You can use ternary operator for assigning for example:
int n = 0, y = 1;
n = y == 1 ? 0 : 1;

Resources