This isn't a bug.
In D, ?: has higher precedence than =, so
true ? stt = "AA" : stt = "BB"
means
(true ? (stt = "AA") : stt) = "BB",
in line with C and other languages, but notably not C++.
The operator precedence should be documented somewhere, though; while there is a table in TDPL (p. 61 ff.) and on the Wiki (https://wiki.dlang.org/Operator_precedence), I can't seem to find it on dlang.org/spec.
---
Changing this to an enhancement request, as we should really consider requiring explicit parenthesization for this sort of error-prone code, similar to how we disallow assignment expressions in if statements.
Comment #2 by code — 2018-04-07T21:52:58Z
(Note that this _is_ part of the specification in form of the grammar. Assignment is defined as
AssignExpression:
ConditionalExpression
ConditionalExpression = AssignExpression
ConditionalExpression += AssignExpression
ConditionalExpression -= AssignExpression
ConditionalExpression *= AssignExpression
ConditionalExpression /= AssignExpression
ConditionalExpression %= AssignExpression
ConditionalExpression &= AssignExpression
ConditionalExpression |= AssignExpression
ConditionalExpression ^= AssignExpression
ConditionalExpression ~= AssignExpression
ConditionalExpression <<= AssignExpression
ConditionalExpression >>= AssignExpression
ConditionalExpression >>>= AssignExpression
ConditionalExpression ^^= AssignExpression
which unambiguously specifies the precedence.)
Comment #3 by Patrick.Schluter — 2018-04-08T16:57:16Z
(In reply to David Nadlinger from comment #1)
> This isn't a bug.
>
> In D, ?: has higher precedence than =, so
>
> true ? stt = "AA" : stt = "BB"
>
> means
>
> (true ? (stt = "AA") : stt) = "BB",
>
> in line with C and other languages, but notably not C++.
>
> The operator precedence should be documented somewhere, though; while there
> is a table in TDPL (p. 61 ff.) and on the Wiki
> (https://wiki.dlang.org/Operator_precedence), I can't seem to find it on
> dlang.org/spec.
>
> ---
>
> Changing this to an enhancement request, as we should really consider
> requiring explicit parenthesization for this sort of error-prone code,
> similar to how we disallow assignment expressions in if statements.
How on earth can
(true ? (stt = "AA") : stt) = "BB"
compile?
(stt = "AA") is not a lvalue or is it?
It looks like D compiles
int a, b;
(a=1)=2;
without problem. That's what surprizing here (at least for a C guy), not the precedence of the ternary.
Comment #4 by code — 2018-04-08T17:00:57Z
(In reply to Patrick Schluter from comment #3)
> (stt = "AA") is not a lvalue or is it?
It is, just as in C++.
Comment #5 by kdevel — 2018-04-08T20:04:52Z
(In reply to David Nadlinger from comment #1)
> (true ? (stt = "AA") : stt) = "BB",
>
> in line with C and other languages, but notably not C++.
The value of the ternary conditional operator of C is not an l-value. Hence the compilations fails (for a conforming compiler). JavaScript/ECMAScript follows C++. C# does probably not allow a free ternary conditional. The only language I found which behaves like D is perl.