March 24, 2021
On Wednesday, 24 March 2021 at 17:38:14 UTC, H. S. Teoh wrote:
> Since there is only one sensible meaning of `a = b = c`...

If I'm reading the spec on expressions right, the compiler is actually free to interpret that as (a = b) = c if it feels particularly adventurous. The evaluation order of assignment operations is explicitly undefined...

I think the intent was to not force an order of execution of subexpressions on either side of a single assignment (e.g. a[i] = a[j] with an opIndex implementation), but this seems to leave too much leeway for assignment chains.

Side note: having an undefined order of execution of the sides of an assignment can be a great source of fun (read: surprising) bugs in C++. Just going from GCC to clang switches the order around.
March 24, 2021
On Wednesday, 24 March 2021 at 18:38:07 UTC, Gregor Mückl wrote:
> On Wednesday, 24 March 2021 at 17:38:14 UTC, H. S. Teoh wrote:
>> Since there is only one sensible meaning of `a = b = c`...
>
> If I'm reading the spec on expressions right, the compiler is actually free to interpret that as (a = b) = c if it feels particularly adventurous. The evaluation order of assignment operations is explicitly undefined...

Where is the spec you referring to?

Let's fix the spec first then.
March 24, 2021
On Wednesday, 24 March 2021 at 18:38:07 UTC, Gregor Mückl wrote:
> On Wednesday, 24 March 2021 at 17:38:14 UTC, H. S. Teoh wrote:
>> Since there is only one sensible meaning of `a = b = c`...
>
> If I'm reading the spec on expressions right, the compiler is actually free to interpret that as (a = b) = c if it feels particularly adventurous. The evaluation order of assignment operations is explicitly undefined...

You're probably mistaken. Evaluation order does not mean associating an expression differently. Assignment is right associative in any case:

    a = b = c

is the same as

    a = (b = c)

but when *evaluating* a, b, and c, the compiler can choose to evaluate e.g. b first. It makes more sense if you look at functions retuning by `ref`:


    int _a, _b, _c;
    ref int a() { return _a; }
    ref int b() { return _b; }
    ref int c() { return _c; }

Then, in (parentheses are optional in D)

    a() = (b() = c())

the compiler could execute b() first, a() second and c() last, getting references (i.e. pointers) and assigning them in the associated way.
March 24, 2021
On Wed, Mar 24, 2021 at 06:38:07PM +0000, Gregor Mückl via Digitalmars-d wrote:
> On Wednesday, 24 March 2021 at 17:38:14 UTC, H. S. Teoh wrote:
> > Since there is only one sensible meaning of `a = b = c`...
> 
> If I'm reading the spec on expressions right, the compiler is actually free to interpret that as (a = b) = c if it feels particularly adventurous. The evaluation order of assignment operations is explicitly undefined...

Link to spec please?  If what you say is true, that sounds like an error in the spec.  Walter has said many times that evaluation order in D is left to right, unless otherwise indicated. Having it unspecified just leads to a huge can o' worms.


[...]
> Side note: having an undefined order of execution of the sides of an assignment can be a great source of fun (read: surprising) bugs in C++. Just going from GCC to clang switches the order around.

Exactly, this is why Walter is against having unspecific order of execution.  This supposed "optimization opportunity" leads to far more trouble than it's worth.


T

-- 
What doesn't kill me makes me stranger.
March 24, 2021
On Wednesday, 24 March 2021 at 19:29:54 UTC, Q. Schroll wrote:
> On Wednesday, 24 March 2021 at 18:38:07 UTC, Gregor Mückl wrote:
>> On Wednesday, 24 March 2021 at 17:38:14 UTC, H. S. Teoh wrote:
>>> Since there is only one sensible meaning of `a = b = c`...
>>
>> If I'm reading the spec on expressions right, the compiler is actually free to interpret that as (a = b) = c if it feels particularly adventurous. The evaluation order of assignment operations is explicitly undefined...
>
> You're probably mistaken. Evaluation order does not mean associating an expression differently. Assignment is right associative in any case:
>
>     a = b = c
>
> is the same as
>
>     a = (b = c)
>
> but when *evaluating* a, b, and c, the compiler can choose to evaluate e.g. b first. It makes more sense if you look at functions retuning by `ref`:
>
>
>     int _a, _b, _c;
>     ref int a() { return _a; }
>     ref int b() { return _b; }
>     ref int c() { return _c; }
>
> Then, in (parentheses are optional in D)
>
>     a() = (b() = c())
>
> the compiler could execute b() first, a() second and c() last, getting references (i.e. pointers) and assigning them in the associated way.

Right, I've made a mistake and confused order of evaluation and associativity in my first look at the spec. Oops :(

Still, I think that this part the spec isn't actually well written. I'm mostly referring to the section on order of evaluation, but the rest of this page is also relevant: https://dlang.org/spec/expression.html#order-of-evaluation

What I'm missing is a clear statement about operator associativity and operator precedence for expressions. When I'm reading the spec without applying any additional common sense, a + b * c could be evaluated strictly from left to right because I don't see how mathematical operator precedence is explicitly established anywhere. Neither do I see associativity established anywhere. If assignment was clearly defined to be right-associative, things would be unambiguous.


March 24, 2021
On Wednesday, 24 March 2021 at 21:28:24 UTC, H. S. Teoh wrote:
> On Wed, Mar 24, 2021 at 06:38:07PM +0000, Gregor Mückl via Digitalmars-d wrote:
>> On Wednesday, 24 March 2021 at 17:38:14 UTC, H. S. Teoh wrote:
>> > Since there is only one sensible meaning of `a = b = c`...
>> 
>> If I'm reading the spec on expressions right, the compiler is actually free to interpret that as (a = b) = c if it feels particularly adventurous. The evaluation order of assignment operations is explicitly undefined...
>
> Link to spec please?  If what you say is true, that sounds like an error in the spec.  Walter has said many times that evaluation order in D is left to right, unless otherwise indicated. Having it unspecified just leads to a huge can o' worms.
>

See point 1 under "Implementation Defined": https://dlang.org/spec/expression.html#order-of-evaluation

"The order of evaluation of the operands of AssignExpression."
March 24, 2021
On Wednesday, 24 March 2021 at 21:38:20 UTC, Gregor Mückl wrote:
> [...]

I'd actually like my claim to be proven wrong. I just can't seem to accomplish that myself ;).

March 24, 2021
On Wed, Mar 24, 2021 at 09:40:07PM +0000, Gregor Mückl via Digitalmars-d wrote:
> On Wednesday, 24 March 2021 at 21:28:24 UTC, H. S. Teoh wrote:
> > On Wed, Mar 24, 2021 at 06:38:07PM +0000, Gregor Mückl via Digitalmars-d wrote:
> > > On Wednesday, 24 March 2021 at 17:38:14 UTC, H. S. Teoh wrote:
> > > > Since there is only one sensible meaning of `a = b = c`...
> > > 
> > > If I'm reading the spec on expressions right, the compiler is actually free to interpret that as (a = b) = c if it feels particularly adventurous. The evaluation order of assignment operations is explicitly undefined...
> > 
> > Link to spec please?  If what you say is true, that sounds like an error in the spec.  Walter has said many times that evaluation order in D is left to right, unless otherwise indicated. Having it unspecified just leads to a huge can o' worms.
> > 
> 
> See point 1 under "Implementation Defined": https://dlang.org/spec/expression.html#order-of-evaluation
> 
> "The order of evaluation of the operands of AssignExpression."

The keyword here is "operands". The order of evaluation of the *operands* is implementation-defined; the order of the evaluation of the assignment *operators* is from right to left.


T

-- 
Only boring people get bored. -- JM
March 24, 2021
On 24.03.21 22:38, Gregor Mückl wrote:
> What I'm missing is a clear statement about operator associativity and operator precedence for expressions. When I'm reading the spec without applying any additional common sense, a + b * c could be evaluated strictly from left to right because I don't see how mathematical operator precedence is explicitly established anywhere. Neither do I see associativity established anywhere. If assignment was clearly defined to be right-associative, things would be unambiguous.

It's in the grammar.

`a + b * c` is parsed as (skipping the boring parts):

AddExpression
  "a"
  "+"
  MulExpression
    "b"
    "*"
    "c"

And `a = b = c`:

AssignExpression
  "a"
  "="
  AssignExpression
    "b"
    "="
    "c"
1 2 3
Next ›   Last »