【问题标题】:error: expression is not assignable ternary operator错误:表达式不可赋值三元运算符
【发布时间】:2019-03-27 12:50:39
【问题描述】:

我有以下代码,MPLABX XC8 编译器给出了这个错误:

错误:表达式不可赋值

U1ERRIRbits.RXFOIF ? uart1.oerr = 1 : uart1.oerr = 0;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^

这里是相关的代码部分:

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;

当我使用时,同样的事情不会出错

if (U1ERRIRbits.RXFOIF) 
    uart1.oerr = 1;
else 
    uart1.oerr = 0;

不明白为什么?

【问题讨论】:

  • uart1.oerr = U1ERRIRbits.RXFOIF? 1:0; 怎么样?
  • 试试U1ERRIRbits.RXFOIF ? uart1.oerr = 1 : (uart1.oerr = 0)。条件绑定比赋值强。 C Operator Precedence.
  • @Blaze 谢谢!看起来好多了@Scheff 谢谢你的回答! :)
  • 这是什么意思? “我使用时相同的东西不会出错”这根本不是一回事!三元运算符(与任何运算符一样)用作表达式的一部分。表达式不创建左值。在您的替代版本中,您有单独的语句,您可以在其中将值分配给左值。
  • 另一个一般规则:在实际需要之前避免使用?:。这一点也不常见。

标签: c struct union ternary


【解决方案1】:
U1ERRIRbits.RXFOIF ? uart1.oerr = 1 : uart1.oerr = 0;

被解释为:

(U1ERRIRbits.RXFOIF ? uart1.oerr = 1 : uart1.oerr) = 0;

哪个试图将0 分配给...?如果你想使用这样的结构,你需要大括号:

U1ERRIRbits.RXFOIF ? uart1.oerr = 1 : (uart1.oerr = 0);

或者更好:

uart1.oerr = U1ERRIRbits.RXFOIF ? 1 : 0;

或:

uart1.oerr = !!U1ERRIRbits.RXFOIF;

或:

uart1.oerr = (bool)U1ERRIRbits.RXFOIF;

或者真的只是:

uart1.oerr = U1ERRIRbits.RXFOIF;

作为typeof(uart1.oerr) == bool,对于非零值,该值将隐式转换为1,对于零值,该值将隐式转换为0

【讨论】:

    【解决方案2】:

    答案很简单,由于C operator precedence

    U1ERRIRbits.RXFOIF ? uart1.oerr = 1 : uart1.oerr = 0;
    

    编译为

    (U1ERRIRbits.RXFOIF ? uart1.oerr = 1 : uart1.oerr) = 0;
    

    在 C 中,条件不提供 LValue。因此,这是一个编译器错误。

    一种解决方案是使用括号:

    U1ERRIRbits.RXFOIF ? uart1.oerr = 1 : (uart1.oerr = 0);
    

    请注意,uart1.oerr = 1 不需要括号,因为 ?: 的作用类似于括号(三元运算符的特殊性)。

    Kamils answer中已经提到了更简单的解决方案...

    【讨论】:

      猜你喜欢
      • 2013-04-21
      • 1970-01-01
      • 1970-01-01
      • 2012-01-13
      • 2013-06-28
      • 1970-01-01
      • 1970-01-01
      • 2021-06-10
      • 2013-12-22
      相关资源
      最近更新 更多