问题
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?
回答1:
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.
回答2:
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...
来源:https://stackoverflow.com/questions/55377646/error-expression-is-not-assignable-ternary-operator