Thread overview | |||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
October 31, 2018 Fun surprising things | ||||
---|---|---|---|---|
| ||||
What's the output of this program? (Try to figure it out without running it.) ``` int c = 0; int a() { return c++; } int b() { return c--; } void main() { import std.conv : to; import std.stdio : writeln; writeln(to!string(a) ~ to!string(b)); } ``` If your answer is "10" then you're wrong. You can get the result and answer here: https://run.dlang.io/is/idZurR |
November 01, 2018 Re: Fun surprising things | ||||
---|---|---|---|---|
| ||||
Posted in reply to bauss | There isn't really any reason for it to be like this. Assembly: .text._Dmain segment assume CS:.text._Dmain _Dmain: push RBP mov RBP,RSP sub RSP,010h call int onlineapp.b()@PLT32 mov RDI,RAX call pure nothrow @safe immutable(char)[] std.conv.to!(immutable(char)[]).to!(int).to(int)@PLT32 mov RCX,RAX mov R8,RDX mov -010h[RBP],RCX mov -8[RBP],R8 call int onlineapp.a()@PLT32 mov RDI,RAX call pure nothrow @safe immutable(char)[] std.conv.to!(immutable(char)[]).to!(int).to(int)@PLT32 mov RSI,RAX mov R8,-8[RBP] mov RCX,-010h[RBP] mov RDI,TypeInfo_Aya.__init@GOTPCREL[RIP] call _d_arraycatT@PLT32 mov RDI,RAX mov RSI,RDX call @safe void std.stdio.writeln!(immutable(char)[]).writeln(immutable(char)[])@PLT32 xor EAX,EAX leave ret |
October 31, 2018 Re: Fun surprising things | ||||
---|---|---|---|---|
| ||||
Posted in reply to bauss | On Wednesday, 31 October 2018 at 14:00:14 UTC, bauss wrote: > If your answer is "10" then you're wrong. https://dlang.org/spec/expression.html#order-of-evaluation > 2. Implementation Defined: > The order of evaluation of the operands of AssignExpression. > ... So indeed, both answers are "right". |
October 31, 2018 Re: Fun surprising things | ||||
---|---|---|---|---|
| ||||
Posted in reply to bauss | On Wednesday, 31 October 2018 at 14:00:14 UTC, bauss wrote:
> What's the output of this program? (Try to figure it out without running it.)
>
> ```
> int c = 0;
>
> int a()
> {
> return c++;
> }
>
> int b()
> {
> return c--;
> }
>
> void main()
> {
> import std.conv : to;
> import std.stdio : writeln;
>
> writeln(to!string(a) ~ to!string(b));
> }
> ```
>
> If your answer is "10" then you're wrong.
>
> You can get the result and answer here: https://run.dlang.io/is/idZurR
01 is the other possible result. It all depends in what order a and b are called. ~ is not a sequence point (does D even have that typical C notion of sequence points?) so the order of evaluation is at the discretion of the compiler.
therefore -10 or 01 are both right.
|
October 31, 2018 Re: Fun surprising things | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stanislav Blinov | On 10/31/18 10:18 AM, Stanislav Blinov wrote:
> On Wednesday, 31 October 2018 at 14:00:14 UTC, bauss wrote:
>
>> If your answer is "10" then you're wrong.
>
> https://dlang.org/spec/expression.html#order-of-evaluation
>
>> 2. Implementation Defined:
>> The order of evaluation of the operands of AssignExpression.
>> ...
>
> So indeed, both answers are "right".
No, the correct answer is "01", according to left to right evaluation.
a should be evaluated first, which returns 0, and increments c by 1.
Then b is evaluated, returning 1, and decrementing c by 1.
But the assembly shows that this binary expression is evaluated right to left, which is not what the spec says.
BUT, the lowering in the compiler could change arr1 ~ arr2 to a function call (arrayCat(arr1, arr2)), which then allows the compiler to evaluate in right to left order.
So the inconsistency in the spec ("binary expressions are left to right", "function arguments are implementation defined order") leaves a gaping hole. What happens when a binary expression lowers to a function call?
-Steve
|
October 31, 2018 Re: Fun surprising things | ||||
---|---|---|---|---|
| ||||
Posted in reply to Patrick Schluter | On Wednesday, 31 October 2018 at 14:54:48 UTC, Patrick Schluter wrote:
> On Wednesday, 31 October 2018 at 14:00:14 UTC, bauss wrote:
>> What's the output of this program? (Try to figure it out without running it.)
>>
>> ```
>> int c = 0;
>>
>> int a()
>> {
>> return c++;
>> }
>>
>> int b()
>> {
>> return c--;
>> }
>>
>> void main()
>> {
>> import std.conv : to;
>> import std.stdio : writeln;
>>
>> writeln(to!string(a) ~ to!string(b));
>> }
>> ```
>>
>> If your answer is "10" then you're wrong.
>>
>> You can get the result and answer here: https://run.dlang.io/is/idZurR
>
> 01 is the other possible result. It all depends in what order a and b are called. ~ is not a sequence point (does D even have that typical C notion of sequence points?) so the order of evaluation is at the discretion of the compiler.
>
> therefore -10 or 01 are both right.
And I just checked, ldc gives 01 as response.
|
October 31, 2018 Re: Fun surprising things | ||||
---|---|---|---|---|
| ||||
Posted in reply to Patrick Schluter | On Wednesday, 31 October 2018 at 15:00:52 UTC, Patrick Schluter wrote:
> And I just checked, ldc gives 01 as response.
and gdc "-10"
|
October 31, 2018 Re: Fun surprising things | ||||
---|---|---|---|---|
| ||||
Posted in reply to bauss | On Wednesday, 31 October 2018 at 14:00:14 UTC, bauss wrote:
> What's the output of this program? (Try to figure it out without running it.)
>
> ```
> int c = 0;
>
> int a()
> {
> return c++;
> }
>
> int b()
> {
> return c--;
> }
>
> void main()
> {
> import std.conv : to;
> import std.stdio : writeln;
>
> writeln(to!string(a) ~ to!string(b));
> }
> ```
>
> If your answer is "10" then you're wrong.
>
> You can get the result and answer here: https://run.dlang.io/is/idZurR
Hopefully the pain of working with such code teaches one to not write such code. Yes, you can write FORTRAN in D, but that doesn't mean it's a good idea to do so.
|
October 31, 2018 Re: Fun surprising things | ||||
---|---|---|---|---|
| ||||
Posted in reply to bachmeier | On Wednesday, 31 October 2018 at 16:05:47 UTC, bachmeier wrote: > On Wednesday, 31 October 2018 at 14:00:14 UTC, bauss wrote: >> What's the output of this program? (Try to figure it out without running it.) >> >> ``` >> int c = 0; >> >> int a() >> { >> return c++; >> } >> >> int b() >> { >> return c--; >> } >> >> void main() >> { >> import std.conv : to; >> import std.stdio : writeln; >> >> writeln(to!string(a) ~ to!string(b)); >> } >> ``` >> >> If your answer is "10" then you're wrong. >> >> You can get the result and answer here: https://run.dlang.io/is/idZurR > > Hopefully the pain of working with such code teaches one to not write such code. Yes, you can write FORTRAN in D, but that doesn't mean it's a good idea to do so. https://www.youtube.com/watch?v=lbp6vwdnE0k&start=1296 |
October 31, 2018 Re: Fun surprising things | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Wednesday, 31 October 2018 at 15:00:26 UTC, Steven Schveighoffer wrote: > On 10/31/18 10:18 AM, Stanislav Blinov wrote: >> On Wednesday, 31 October 2018 at 14:00:14 UTC, bauss wrote: >> >>> If your answer is "10" then you're wrong. >> >> https://dlang.org/spec/expression.html#order-of-evaluation >> >>> 2. Implementation Defined: >>> The order of evaluation of the operands of AssignExpression. >>> ... >> >> So indeed, both answers are "right". > > No, the correct answer is "01", according to left to right evaluation. > > a should be evaluated first, which returns 0, and increments c by 1. Not in this case, no. > Then b is evaluated, returning 1, and decrementing c by 1. > > But the assembly shows that this binary expression is evaluated right to left, which is not what the spec says. > > BUT, the lowering in the compiler could change arr1 ~ arr2 to a function call (arrayCat(arr1, arr2)), which then allows the compiler to evaluate in right to left order. Could, or could not. It's implementation-defined. > So the inconsistency in the spec ("binary expressions are left to right", "function arguments are implementation defined order") leaves a gaping hole. What happens when a binary expression lowers to a function call? You're misreading the spec. The relevant part is the one I quoted. There's no left-to-right evaluation rule here. It's not a binary expression, it's an argument list; in this case - one argument, which is a CatExpression, which is an AssignExpression, the order of evaluation of it's operands is implementation-defined. |
Copyright © 1999-2021 by the D Language Foundation