Thread overview | |||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 07, 2018 that is bug? | ||||
---|---|---|---|---|
| ||||
string stt = "none"; true?writeln("AA"):writeln("BB"); ///Out:AA true?stt="AA":stt="BB"; <<<<-----///Out:BB writeln(stt); |
April 07, 2018 Re: that is bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to sdvcn | On Saturday, April 07, 2018 09:07:48 sdvcn via Digitalmars-d wrote:
> string stt = "none";
> true?writeln("AA"):writeln("BB"); ///Out:AA
> true?stt="AA":stt="BB"; <<<<-----///Out:BB
> writeln(stt);
Assignment takes precendence over the ternary operator. So, no, I don't think that it is. Putting parens around the assignment expressions makes it print AA. As it stands, it evaluates both assignment expressions before evaluating the ternary operator.
In general, I'd advise against using expressions with side effects in the branches of a ternary operator, since it's easy to end up with a result that doesn't do what you think it does (or which readers of your code will misinterpret) - or you can just always use parens, but the folks who do that generally end up using parens when they're completely unnecessary, which IMHO makes the code uglier and harder to read. Either way, if you're doing assignment, it generally makes more sense to put it outside the ternary operator. e.g.
stt = condition ? "AA" : "BB";
Also FYI, questions should generally be asked in the D.Learn newsgroup/forum instead of the main newsgroup/forum, which is for more general discussions on D and how to improve it.
- Jonathan M Davis
|
April 07, 2018 Re: that is bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to sdvcn | On Saturday, 7 April 2018 at 09:07:48 UTC, sdvcn wrote:
>
> true?stt="AA":stt="BB"; <<<<-----///Out:BB
It's an UB.
Not a bug.
|
April 07, 2018 Re: that is bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bauss | On Saturday, 7 April 2018 at 10:25:19 UTC, bauss wrote:
> On Saturday, 7 April 2018 at 09:07:48 UTC, sdvcn wrote:
>>
>> true?stt="AA":stt="BB"; <<<<-----///Out:BB
>
> It's an UB.
>
> Not a bug.
I want `condition ? expr1 : expr2` to behave like:
-----
auto qc( alias condition, string expr1, string expr2)() {
if( condition) {
return mixin( expr1);
} else {
return mixin( expr2);
}
}
-----
|
April 07, 2018 Re: that is bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to meppl | On Saturday, 7 April 2018 at 11:19:44 UTC, meppl wrote: > On Saturday, 7 April 2018 at 10:25:19 UTC, bauss wrote: >> On Saturday, 7 April 2018 at 09:07:48 UTC, sdvcn wrote: >>> >>> true?stt="AA":stt="BB"; <<<<-----///Out:BB >> >> It's an UB. >> >> Not a bug. > > > I want `condition ? expr1 : expr2` to behave like: > > ----- > auto qc( alias condition, string expr1, string expr2)() { > if( condition) { > return mixin( expr1); > } else { > return mixin( expr2); > } > } > ----- You can do so today with lazy: --- import std.stdio; auto qc(E1, E2)(bool condition, lazy E1 expr1, lazy E2 expr2) { if (condition) { return expr1; } else { return expr2; } } void main() { qc(true, "A".writeln, "B".writeln); string s; qc(true, s = "A", s = "B"); s.writeln; } --- https://run.dlang.io/is/ymZBht https://dlang.org/articles/lazy-evaluation.html |
April 07, 2018 Re: that is bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Saturday, 7 April 2018 at 09:56:43 UTC, Jonathan M Davis wrote: >> true?stt="AA":stt="BB"; <<<<-----///Out:BB [...] > Assignment takes precendence over the ternary operator. That's not true. Not in D and not in C/C++ https://wiki.dlang.org/Operator_precedence http://en.cppreference.com/w/c/language/operator_precedence#cite_note-2 > So, no, I don't think that it is. Putting parens around the assignment expressions makes it print AA. It should not matter if there are parens around the assignment. > As it stands, it evaluates both assignment expressions before evaluating the ternary operator. That is not true in C/C++, let me quote from a C standard (draft), § 6.1.5 conditional operator: [this is about <first op> ? <second op> : <third op>] "Semantics 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)" According to https://dlang.org/spec/expression.html#conditional_expressions the same shall be valid for D. Hence when true ? s = A : s = B; or true ? (s = A) : (s = B); does not yield A for s it's a bug. |
April 07, 2018 Re: that is bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bauss | On Saturday, 7 April 2018 at 10:25:19 UTC, bauss wrote:
> On Saturday, 7 April 2018 at 09:07:48 UTC, sdvcn wrote:
>>
>> true?stt="AA":stt="BB"; <<<<-----///Out:BB
>
> It's an UB.
>
> Not a bug.
Why UB? stt is only modified once.
|
April 07, 2018 Re: that is bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to kdevel | On Saturday, April 07, 2018 14:29:15 kdevel via Digitalmars-d wrote: > On Saturday, 7 April 2018 at 10:25:19 UTC, bauss wrote: > > On Saturday, 7 April 2018 at 09:07:48 UTC, sdvcn wrote: > >> true?stt="AA":stt="BB"; <<<<-----///Out:BB > > > > It's an UB. > > > > Not a bug. > > Why UB? stt is only modified once. It's modified twice. This import std.stdio; struct S { S opAssign(string str) { writeln(str); return S.init; } } void main() { S stt; true ? stt = "AA" : stt = "BB"; } prints AA BB whereas this import std.stdio; struct S { S opAssign(string str) { writeln(str); return S.init; } } void main() { S stt; true ? (stt = "AA") : (stt = "BB"); } prints AA However, similar code in C++ #include <stdio.h> class C { public: C& operator=(int i) { printf("%d\n", i); return *this; } }; int main() { C c; true ? c = 42 : c = 29; return 0; } prints the first value only, which would imply (though not guarantee) that the D behavior is a bug. - Jonathan M Davis |
April 07, 2018 Re: that is bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to kdevel | On Saturday, April 07, 2018 14:28:05 kdevel via Digitalmars-d wrote:
> On Saturday, 7 April 2018 at 09:56:43 UTC, Jonathan M Davis wrote:
> >> true?stt="AA":stt="BB"; <<<<-----///Out:BB
>
> [...]
>
> > Assignment takes precendence over the ternary operator.
>
> That's not true. Not in D and not in C/C++ https://wiki.dlang.org/Operator_precedence http://en.cppreference.com/w/c/language/operator_precedence#cite_note-2
>
> > So, no, I don't think that it is. Putting parens around the assignment expressions makes it print AA.
>
> It should not matter if there are parens around the assignment.
>
> > As it stands, it evaluates both assignment expressions before evaluating the ternary operator.
>
> That is not true in C/C++, let me quote from a C standard
> (draft), § 6.1.5 conditional operator:
>
> [this is about <first op> ? <second op> : <third op>]
>
> "Semantics
>
> 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)"
>
> According to
>
> https://dlang.org/spec/expression.html#conditional_expressions
>
> the same shall be valid for D. Hence when
>
> true ? s = A : s = B;
>
> or
>
> true ? (s = A) : (s = B);
>
> does not yield A for s it's a bug.
You're right. It's what I get for responding too early in the morning.
- Jonathan M Davis
|
April 07, 2018 Re: that is bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Saturday, 7 April 2018 at 14:43:53 UTC, Jonathan M Davis wrote: > On Saturday, April 07, 2018 14:29:15 kdevel via Digitalmars-d wrote: >> On Saturday, 7 April 2018 at 10:25:19 UTC, bauss wrote: >> > On Saturday, 7 April 2018 at 09:07:48 UTC, sdvcn wrote: >> >> true?stt="AA":stt="BB"; <<<<-----///Out:BB >> > >> > It's an UB. >> > >> > Not a bug. >> >> Why UB? stt is only modified once. > > It's modified twice. So we have diffrent behavior of D wrt to C. > [...] which would imply (though not guarantee) that the D behavior is a bug. After rereading https://dlang.org/spec/expression.html#conditional_expressions carefully I found that Unlike § 6.1.5 of the C standard the "only" is missing in the D docs. |
Copyright © 1999-2021 by the D Language Foundation