条件运算符的结果是左值还是右值?

Is the result of the conditional operator an lvalue or rvalue?

我们知道条件运算符 returns 如果它的 Expr2Expr3 是相同类型的左值,则它是一个左值,否则它 returns 是一个右值:

int main(){
   int a = 0, b = 0;
   (a == 1 ? a : b) = 1; // C++ OK. C: error. lvalue needed

   return 0;
}

这是 C:

上的输出
main.c: In function ‘main’:
main.c:8:20: error: lvalue required as left operand of assignment
(a == 1 ? a : b) = 1;
                ^

在C中,条件运算符的结果1是一个右值(C标准术语中的“值”),因为C 2018 6.3.2.1 2说:

Except when it is the operand of the sizeof operator, the unary & operator, the ++ operator, the -- operator, or the left operand of the . operator or an assignment operator, an lvalue that does not have array type is converted to the value stored in the designated object (and is no longer an lvalue);…

因此,虽然条件运算符的结果是它的第二个或第三个操作数,但该操作数已转换为一个值,不再是左值。

M.M 所述,您可以通过选择操作数的地址然后应用 *:

来获得与选择左值相同的效果
*(a == 1 ? &a : &b) = 1;

脚注

1 条件运算符的结果不是 return 值,因为不涉及函数调用,所以不存在 call-and-return, 只是一个表达式求值。

这是 C++ 和 C 不同的情况之一。在 C 中,条件运算符产生右值,因此它不能位于赋值的左侧。

表达式1?表达式 2 : 表达式 3 如果表达式 1 具有真(非零)值,则整个条件表达式采用与表达式 2 相同的值。如果表达式 1 具有假(空)值,则整个条件表达式将获得与表达式 3 相同的值。

P r i m e r s
(5 > 3) ? 1 : 2 gets the value 1.
(3 > 5) ? 1 ; 2 gets the value 2.
(a > b) ? a : b gets a larger value among a or b. 
   The conditional operation itself is not a function that 
  returns a value.

this C11 Draft Standard中有一个脚注明确指出条件运算符的结果不是左值:

6.5.15 Conditional operator


Semantics

4    The first operand is evaluated; there is a sequence point between its evaluation and the evaluation of the second or third operand (whichever is evaluated). The second operand is evaluated only if the first compares unequal to 0; the third operand is evaluated only if the first compares equal to 0; the result is the value of the second or third operand (whichever is evaluated), converted to the type described below.110)


110) A conditional expression does not yield an lvalue.

此外,in this later draft Standard(日期为 2019 年 3 月),措辞没有显着变化(除了其中的脚注编号为 116,而不是 110)。