I have the following code and MPLABX XC8 compiler gives this error:
error: expression is not assignable
U1ERRIRbits.RXFOIF ? uart1.oerr = 1 : uart1.oerr = 0; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
Here is the relevant code section:
typedef union {
struct {
bool ferr : 1; // FERIF Framing Error
bool aerr : 1; // ABDOVF Error
bool oerr : 1; // RXFOIF Error
bool ready : 1; // Data Ready to be read
uint8_t reserved : 4;
};
uint8_t status;
}uart1_status_t;
static volatile uart1_status_t uart1;
U1ERRIRbits.RXFOIF ? uart1.oerr = 1 : uart1.oerr = 0;
Same thing does not give error when I use
if (U1ERRIRbits.RXFOIF)
uart1.oerr = 1;
else
uart1.oerr = 0;
Do not understand why?
U1ERRIRbits.RXFOIF ? uart1.oerr = 1 : uart1.oerr = 0;
is interpreted as:
(U1ERRIRbits.RXFOIF ? uart1.oerr = 1 : uart1.oerr) = 0;
Which tries to assign 0
to ...? If you want to use such construct, you need braces:
U1ERRIRbits.RXFOIF ? uart1.oerr = 1 : (uart1.oerr = 0);
Or better:
uart1.oerr = U1ERRIRbits.RXFOIF ? 1 : 0;
or:
uart1.oerr = !!U1ERRIRbits.RXFOIF;
or:
uart1.oerr = (bool)U1ERRIRbits.RXFOIF;
or really just:
uart1.oerr = U1ERRIRbits.RXFOIF;
as typeof(uart1.oerr) == bool
, the value will be implicitly converted to 1
for nonzero values or 0
for zero.
The answer is simple that, due to C operator precedence,
U1ERRIRbits.RXFOIF ? uart1.oerr = 1 : uart1.oerr = 0;
is compiled as
(U1ERRIRbits.RXFOIF ? uart1.oerr = 1 : uart1.oerr) = 0;
In C, a condition doesn't provide an LValue. Hence, this is a compiler error.
One solution would be to use parentheses:
U1ERRIRbits.RXFOIF ? uart1.oerr = 1 : (uart1.oerr = 0);
Please note, that uart1.oerr = 1
doesn't need parentheses as ?
and :
act like parentheses (a specialty of the ternary operator).
The even simpler solutions are already mentioned in Kamils answer...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With