Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c

if-statement

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;
like image 678
Erdős András Avatar asked Dec 12 '25 08:12

Erdős András


2 Answers

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);
like image 139
dbush Avatar answered Dec 14 '25 09:12

dbush


I think it should be:

Counter.WriteOut = (adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1)) > 10 ? 1 : 0;
like image 37
Orest Savchak Avatar answered Dec 14 '25 09:12

Orest Savchak



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!