What is wrong with this assignment in a conditional operator?

前端 未结 4 1049
独厮守ぢ
独厮守ぢ 2021-01-15 09:18

There is an error. Is it wrong to assign a value to a[i] in the following code? Or something is wrong with conditional operators?

#include
#in         


        
4条回答
  •  独厮守ぢ
    2021-01-15 09:40

    This is a bit tricky. There's a nice overview of "effective" operator precedence in C and I'll cite the notes from there explaining your problem *):

    There is a part of the grammar that cannot be represented by a precedence table: an assignment-expression is not allowed as the right hand operand of a conditional operator, so e = a < d ? a++ : a = d is an expression that cannot be parsed, and therefore relative precedence of conditional and assignment operators cannot be described easily.
    However, many C compilers use non-standard expression grammar where ?: is designated higher precedence than =, which parses that expression as e = ( ((a < d) ? (a++) : a) = d ), which then fails to compile due to semantic constraints: ?: is never lvalue and = requires a modifiable lvalue on the left.

    After DavidBowling's findings in the standard (thanks for this work!), the second paragraph above is not entirely correct, or, at least a bit confusing. It's correct that the right-hand operand of ?: cannot be an assignment, but the middle operand can. So for the right-hand side, the ?: "takes precedence" over =, while it doesn't for the middle part. Any part can be a primary expression, therefore paranthesizing to "change precedence" works as expected:

    a[i]>90 ? a[i]=a[i]-32 : (a[i]=a[i]+32);
    

    But, as others have stated, this is needlessly complex anyways, you can achieve what you want with just

    a[i] += a[i]>90 ? -32 : 32;
    

    which is also easier to understand.


    *) To understand the reasoning in this citation, you have to know that lvalue is used in the C standard to describe something that might appear on the left hand side (hence the name) of an assignment (aka can be assigned to). This is a somewhat sloppy definition and is clarified further in the C standard, I think it's enough for the context of this answer.

提交回复
热议问题