Thread overview
Understanding the Behavior of i + ++i in D Language
Aug 23
Me'vâ
Aug 24
IchorDev
August 23

Hello,

I'm working with a simple piece of code in the D language and encountered a result that has left me puzzled. The code snippet is as follows:

import std.stdio:writeln;

void main() {
    int i = 5;
    writeln("Result: ", i + ++i);
}

When I run this, it surprisingly outputs 11. I tried something similar in C before and it gave me 12. I’m curious, why is there a difference? How is i + ++i evaluated in D that it ends up giving 11 instead of 12?

Is there something about operator precedence or evaluation order in D that I'm missing? I'd really appreciate it if someone could break it down for me or point me towards some resources to get a better understanding of what's going on.

Thanks a bunch!

August 23

On Friday, 23 August 2024 at 08:58:16 UTC, Me'vâ wrote:

>
import std.stdio:writeln;

void main() {
    int i = 5;
    writeln("Result: ", i + ++i);
}

When I run this, it surprisingly outputs 11. I tried something similar in C before and it gave me 12. I’m curious, why is there a difference? How is i + ++i evaluated in D that it ends up giving 11 instead of 12?

D: 5 + 6
C++: undefined, could be 6 + 6 if the increment is done first. g++ gives me a warning with -Wall:

inc.cxx: In function ‘int main()’:
inc.cxx:30:26: warning: operation on ‘i’ may be undefined [-Wsequence-point]
   30 |         std::cout << i + ++i << "\n";
      |                          ^~~
>

Is there something about operator precedence or evaluation order in D that I'm missing? I'd really appreciate it if someone could break it down for me or point me towards some resources to get a better understanding of what's going on.

See https://dlang.org/spec/expression.html#order-of-evaluation

>

Binary expressions except for AssignExpression, OrOrExpression, and AndAndExpression are evaluated in lexical order (left-to-right).

So in D, the value of i on the left is always read before the increment on the right.

August 23

On Friday, 23 August 2024 at 09:42:38 UTC, Nick Treleaven wrote:

>

C++: undefined, could be 6 + 6 if the increment is done first. g++ gives me a warning with -Wall:

You asked about C, for some reason I used C++. But it's the same in C, and the error happens with gcc -Wall.

August 24

On Friday, 23 August 2024 at 09:49:27 UTC, Nick Treleaven wrote:

>

On Friday, 23 August 2024 at 09:42:38 UTC, Nick Treleaven wrote:

>

C++: undefined, could be 6 + 6 if the increment is done first. g++ gives me a warning with -Wall:

You asked about C, for some reason I used C++.

I think the ++ might’ve infected your thought process.

August 28

On Friday, 23 August 2024 at 08:58:16 UTC, Me'vâ wrote:

>
writeln("Result: ", i + ++i);

I would definitely expect 11 as result (but I still have K&R on my book shelf, maybe I'm a bit biased). So, when you get 12 with C, I would consider that an error.

August 28
On Wednesday, August 28, 2024 3:44:59 PM MDT Johann Lermer via Digitalmars-d- learn wrote:
> On Friday, 23 August 2024 at 08:58:16 UTC, Me'vâ wrote:
> >     writeln("Result: ", i + ++i);
>
> I would definitely expect 11 as result (but I still have K&R on my book shelf, maybe I'm a bit biased). So, when you get 12 with C, I would consider that an error.

The order of evaluation is unspecified in C code (C often fails to specify such things in order to allow the compiler to do whatever would be the most efficient). So, either answer would be perfectly valid coming from a C compiler, and if it were specified in C, D would follow the same rule, since as a general rule, C code is supposed to be valid D code with the same behavior, or it isn't valid D code.

In general, D locks down the order of evaluation so that the result is consistent, but it's arguably best practice to just avoid expressions that modify a variable while also evaluating that variable in another part of the expression. It makes the code clearer and avoids any order-of-evaluation issues which may exist in the language.

- Jonathan M Davis