www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Order of evaluation of post-increment operator

reply "Gary Willoughby" <dev nomad.so> writes:
I was just taking a look at the following poll[1] about the order 
of evaluation when using the post-increment operator. The 
following D snippet shows an example.

	import std.stdio;

	void main(string[] args)
	{
		auto foo = [0, 0];
		int i = 0;

		foo[i++] = i++; // Woah!

		writefln("%s", foo);
	}

Apparently the C++ equivalent is undefined behaviour but when run 
using D the following result is output:

	[1, 0]

1. Can someone please explain this output?
2. Is there anywhere this order of evaluation is documented?
3. Do you agree this is right?

[1]: 
http://herbsutter.com/2014/12/01/a-quick-poll-about-order-of-evaluation/
Dec 28 2014
next sibling parent "Joakim" <dlang joakim.fea.st> writes:
On Sunday, 28 December 2014 at 14:51:22 UTC, Gary Willoughby 
wrote:
 I was just taking a look at the following poll[1] about the 
 order of evaluation when using the post-increment operator. The 
 following D snippet shows an example.

 	import std.stdio;

 	void main(string[] args)
 	{
 		auto foo = [0, 0];
 		int i = 0;

 		foo[i++] = i++; // Woah!

 		writefln("%s", foo);
 	}

 Apparently the C++ equivalent is undefined behaviour but when 
 run using D the following result is output:

 	[1, 0]

 1. Can someone please explain this output?
 2. Is there anywhere this order of evaluation is documented?
 3. Do you agree this is right?

 [1]: 
 http://herbsutter.com/2014/12/01/a-quick-poll-about-order-of-evaluation/
It has been pointed before that this behavior even varies by D compiler: http://forum.dlang.org/post/swczuwclttmoakpvebut forum.dlang.org One of those many small details that will have to be tightened up in the spec someday.
Dec 28 2014
prev sibling next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Gary Willoughby:

 2. Is there anywhere this order of evaluation is documented?
Currently that code is undefined in D too, and the compiler doesn't even give a compilation error. But Walter has said many times that it will become defined in D (IMHO it must be). Bye, bearophile
Dec 28 2014
parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Sunday, 28 December 2014 at 16:05:32 UTC, bearophile wrote:
 (IMHO it must be).
Disallowing is an alternative to consider. Even defined behaviour can be unintuitive and error prone.
Dec 28 2014
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Marc Schütz:

 On Sunday, 28 December 2014 at 16:05:32 UTC, bearophile wrote:
 (IMHO it must be).
Disallowing is an alternative to consider. Even defined behaviour can be unintuitive and error prone.
Right. Bye, bearophile
Dec 28 2014
prev sibling next sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Sunday, 28 December 2014 at 17:34:52 UTC, Marc Schütz wrote:
 On Sunday, 28 December 2014 at 16:05:32 UTC, bearophile wrote:
 (IMHO it must be).
Disallowing is an alternative to consider. Even defined behaviour can be unintuitive and error prone.
I guess there are cases where it's not easily catchable: void foo(int* p0, int* p1) { (*p0)++ = (*p1)++; } what happens when p0 == p1?
Dec 28 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
John Colvin:

 I guess there are cases where it's not easily catchable:

 void foo(int* p0, int* p1)
 {
     (*p0)++ = (*p1)++;
 }

 what happens when p0 == p1?
The undefined code can be found statically, the run-time values are irrelevant. Bye, bearophile
Dec 28 2014
parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Sunday, 28 December 2014 at 20:25:59 UTC, bearophile wrote:
 John Colvin:

 I guess there are cases where it's not easily catchable:

 void foo(int* p0, int* p1)
 {
    (*p0)++ = (*p1)++;
 }

 what happens when p0 == p1?
The undefined code can be found statically, the run-time values are irrelevant. Bye, bearophile
It depends what you mean by "undefined". Sure, the order of those 2 ++ operations is undefined in all cases, but it doesn't lead to undefined *behaviour* unless the pointers are the same. There's loads of code out there that has undefined order of operations but is invariant w.r.t. said ordering and is therefore correct.
Dec 28 2014
prev sibling parent ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Sun, 28 Dec 2014 17:34:50 +0000
via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:

 On Sunday, 28 December 2014 at 16:05:32 UTC, bearophile wrote:
 (IMHO it must be).
=20 Disallowing is an alternative to consider. Even defined behaviour=20 can be unintuitive and error prone.
yep, 13670 times "yep". ;-)
Dec 28 2014
prev sibling parent "aldanor" <i.s.smirnov gmail.com> writes:
On Sunday, 28 December 2014 at 14:51:22 UTC, Gary Willoughby 
wrote:
 I was just taking a look at the following poll[1] about the 
 order of evaluation when using the post-increment operator. The 
 following D snippet shows an example.

 	import std.stdio;

 	void main(string[] args)
 	{
 		auto foo = [0, 0];
 		int i = 0;

 		foo[i++] = i++; // Woah!

 		writefln("%s", foo);
 	}

 Apparently the C++ equivalent is undefined behaviour but when 
 run using D the following result is output:

 	[1, 0]

 1. Can someone please explain this output?
 2. Is there anywhere this order of evaluation is documented?
 3. Do you agree this is right?

 [1]: 
 http://herbsutter.com/2014/12/01/a-quick-poll-about-order-of-evaluation/
Related thread: http://forum.dlang.org/thread/amngdygrlsogzmefzqko forum.dlang.org#post-l92grb:242q5v:241:40digitalmars.com
Dec 28 2014