Thread overview
Order of evaluation of post-increment operator
Dec 28, 2014
Gary Willoughby
Dec 28, 2014
Joakim
Dec 28, 2014
bearophile
Dec 28, 2014
Marc Schütz
Dec 28, 2014
bearophile
Dec 28, 2014
John Colvin
Dec 28, 2014
bearophile
Dec 28, 2014
John Colvin
Dec 28, 2014
ketmar
Dec 28, 2014
aldanor
December 28, 2014
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/
December 28, 2014
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.
December 28, 2014
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
December 28, 2014
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.
December 28, 2014
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
December 28, 2014
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?
December 28, 2014
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
December 28, 2014
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).
> 
> Disallowing is an alternative to consider. Even defined behaviour can be unintuitive and error prone.
yep, 13670 times "yep". ;-)


December 28, 2014
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
December 28, 2014
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.