March 28, 2014
Someone is sure to ask:

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.8.2-16'
--with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-
languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-
suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/
lib --without-included-gettext --enable-threads=posix --with-gxx-include-
dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/
--enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes
--enable-gnu-unique-object --disable-libmudflap --enable-plugin --with-
system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-
cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-
java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --
with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-
arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --
enable-objc-gc --enable-multiarch --with-arch-32=i586 --with-abi=m64 --
with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-
checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --
target=x86_64-linux-gnu
Thread model: posix
gcc version 4.8.2 (Debian 4.8.2-16)

$ clang -v
Debian clang version 3.3-16 (branches/release_33) (based on LLVM 3.3)
Target: x86_64-pc-linux-gnu
Thread model: posix
March 28, 2014
On 03/28/2014 01:59 PM, Justin Whear wrote:

> $ clang test.c && ./a.out
> test.c:7:7: warning: multiple unsequenced modifications to 'i' [-
> Wunsequenced]
>          i = i++;
>            ~  ^
> 1 warning generated.
> 0
>
>
> Both gcc and clang agree that in C, assigning a post-increment to itself
> results in the original value.

The result of a test program cannot be proof of that. In fact, changing the value of a variable more than once between two sequence points is undefined behavior.

> At least Clang warns, which is good,

It is unfortunate that Clang does not use the word "undefined" there.

> but D is consistent with C's behavior on this point.

It is undefined behavior in both languages.

Ali

March 28, 2014
On 03/28/2014 09:59 PM, Justin Whear wrote:
> On Fri, 28 Mar 2014 19:35:20 +0000, Frustrated wrote:
>
>>
>> either way, all increment i, which actually never happens in D. As was
>> pointed out, VS does it properly... D does it wrong. Accept it and stop
>> trying to validate how D does it so you can say D is correct.
>>
>> Not only is it logically wrong, it is not consistent with previous
>> interpretations of other compilers/languages nor with itself. It is
>> wrong on all levels. Just because you believe in unicorns doesn't prove
>> that they exist. All the evidence says you are wrong.
>>
>
> Nope, Frustrated is the one who is dead wrong.
>

Yup. Also, I don't get point of the hostility.

Executing the side effect of an expression after its value has already been computed and used certainly seems like the least reasonable choice.

> test.c:
> -----------------------------
> #include <stdio.h>
>
> int main()
> {
> 	int i = 0;
> 	i = i++;
> 	printf("%i\n", i);
> 	return 0;
> }
> -----------------------------
>
> $ gcc test.c && ./a.out
> 0
>
> $ clang test.c && ./a.out
> test.c:7:7: warning: multiple unsequenced modifications to 'i' [-
> Wunsequenced]
>          i = i++;
>            ~  ^
> 1 warning generated.
> 0
>
>
> Both gcc and clang agree that in C, assigning a post-increment to itself
> results in the original value.  At least Clang warns, which is good, but
> D is consistent with C's behavior on this point.
>
> Justin
>

Not really. In C, the evaluation order of assignment and increment is actually unspecified and hence a conforming compiler can do it either way.

In D both the "spec" and DMD are confused about the issue of evaluation order. (A related fact is that the "spec" contradicts itself on the issue of function argument evaluation order.)

http://dlang.org/expression.html

"The following binary expressions are evaluated in an implementation-defined order:

AssignExpression, function arguments
...
The evaluation order of function arguments is defined to be left to right."


The example of order-dependent code the "spec" gives is actually the example we are talking about here. I'm not sure what "implementation defined evaluation order" is supposed to mean though. E.g. if it is just the order in which the left and right expression are evaluated before the assignment takes place, then the effect of i=i++; is not actually ambiguous, as 'i' does not have any side effect and is a fine fully evaluated lvalue.

IMHO the most reasonable way out is to just fix a canonical evaluation order (i.e. left-to-right) and then stick to that consistently. Under left-to-right evaluation order in particular, i=i++; should leave the value of i intact. (for int i).

Walter has mentioned on at least one occasion that evaluation should become left-to-right everywhere.
March 28, 2014
On 03/28/2014 10:58 PM, Timon Gehr wrote:
>>
>
> Not really. In C, the evaluation order of assignment and increment is
> actually unspecified and hence a conforming compiler can do it either way.

(Or any other way. Ali is right that in C this is even undefined behaviour. Apparently in C++11 only one of the two behaviours can occur.)

http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points
March 28, 2014
On 03/28/2014 10:56 PM, Ali Çehreli wrote:
>
>  >
>  > Both gcc and clang agree that in C, assigning a post-increment to itself
>  > results in the original value.
>
> The result of a test program cannot be proof of that. In fact, changing
> the value of a variable more than once between two sequence points is
> undefined behavior.
>
>  > At least Clang warns, which is good,
>
> It is unfortunate that Clang does not use the word "undefined" there.
>
>  > but D is consistent with C's behavior on this point.
>
> It is undefined behavior in both languages.

How do you reach that conclusion in the case of D?
March 28, 2014
On 03/28/2014 03:05 PM, Timon Gehr wrote:

> On 03/28/2014 10:56 PM, Ali Çehreli wrote:

>> It is undefined behavior in both languages.
>
> How do you reach that conclusion in the case of D?

By trusting my ignorance on such an execution order in D. :)

Walter has been saying for a while that D will eventually make some execution orders standard (e.g. for function arguments). I would like to know if the situation has improved.

Ali

March 28, 2014
On 03/28/2014 11:12 PM, Ali Çehreli wrote:
>
> By trusting my ignorance on such an execution order in D. :)

Well, unspecified execution order by itself does not imply undefined behaviour.
March 28, 2014
On 03/28/2014 07:04 PM, Frustrated wrote:
>
> I imagine what is going on is that D is creating a temp variable,
> assigning it to the local variable, then incrementing the temp
> variable(since++ increments "after" the assignment).

int tmp = i;
++i;
i = tmp;
March 29, 2014
i hope there will be fixed evaluation order in D. spec writers (especially those who writing specs for C) tends to think 'too close to machine', saying 'unspecified' here and there to allow write compilers that can 'superoptimize' some code.

but what they nearly always forgot is that humans writing programs, not computers. so the language should be *first* clear to human writer and *only then* supports some optimizing tricks.

ideally there should be no 'undefined behavior' in specs at all.

if something is questionable from the point of a language user (not compiler writer), this should be fixed and documented. and declaring it 'undefined behavior' is not the proper way to fix it. ;-)
March 29, 2014
On Friday, 28 March 2014 at 20:59:34 UTC, Justin Whear wrote:
> On Fri, 28 Mar 2014 19:35:20 +0000, Frustrated wrote:
>
>> 
>> either way, all increment i, which actually never happens in D. As was
>> pointed out, VS does it properly... D does it wrong. Accept it and stop
>> trying to validate how D does it so you can say D is correct.
>> 
>> Not only is it logically wrong, it is not consistent with previous
>> interpretations of other compilers/languages nor with itself. It is
>> wrong on all levels. Just because you believe in unicorns doesn't prove
>> that they exist. All the evidence says you are wrong.
>> 
>
> Nope, Frustrated is the one who is dead wrong.
>
> test.c:
> -----------------------------
> #include <stdio.h>
>
> int main()
> {
> 	int i = 0;
> 	i = i++;
> 	printf("%i\n", i);
> 	return 0;
> }
> -----------------------------
>
> $ gcc test.c && ./a.out
> 0
>
> $ clang test.c && ./a.out
> test.c:7:7: warning: multiple unsequenced modifications to 'i' [-
> Wunsequenced]
>         i = i++;
>           ~  ^
> 1 warning generated.
> 0
>
>
> Both gcc and clang agree that in C, assigning a post-increment to itself
> results in the original value.  At least Clang warns, which is good, but
> D is consistent with C's behavior on this point.
>
> Justin


Oh yeah, this makes hell of a lot of sense. I'm the one who's wrong, yet monarch claims it his is correct and yet clang gives a warning. Great logic there! I'll be sure to mark every post you have as special so I can study your logic to become so smart.