Re: [go-nuts] Expression evaluation with side effects

2017-03-21 Thread Ian Lance Taylor
On Tue, Mar 21, 2017 at 10:38 AM, Paul Jolly  wrote:
>> The problem was that I repeatedly mentally misread 'indexing' for 'index
>> evaluation'. As the index is a constant in this case, it lead me to believe
>> it cannot have any effect on the result. But it's the 'indexing', the actual
>> time when the value is loaded using the index, which is exempt from the
>> 'left-to-right' evaluation rule for operands.
>
>
> I actually read the following part of the spec:
>
>> Otherwise, when evaluating the operands of an expression, assignment, or
>> return statement, all function calls, method calls, and communication
>> operations are evaluated in lexical left-to-right order.
>
>
> and inferred "when evaluating the operands of an expression, assignment, or
> return statement" every expression that is not a "function call, method call
> or communication operation" has an undefined order of evaluation, including
> (as the later paragraph clarifies) index expressions.
>
> Consider for example:
>
> https://play.golang.org/p/xGaEDjTuzw
>
> To my understanding, it is undefined when "j-1" evaluates, hence that code
> _might_ panic.
>
> But maybe I read/inferred that incorrectly?

You are correct.  The evaluation of `j`--the actual load of the value
from the global variable--may take place before or after the call to
`foo2`.

Ian

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Expression evaluation with side effects

2017-03-21 Thread Paul Jolly
>
> The problem was that I repeatedly mentally misread 'indexing' for 'index
> evaluation'. As the index is a constant in this case, it lead me to believe
> it cannot have any effect on the result. But it's the 'indexing', the
> actual time when the value is loaded using the index, which is exempt from
> the 'left-to-right' evaluation rule for operands.
>

I actually read the following part of the spec
:

*Otherwise, when evaluating the operands of an expression, assignment, or
> return statement, all function calls, method calls, and communication
> operations are evaluated in lexical left-to-right order.*


and inferred "when evaluating the operands of an expression, assignment, or
return statement" every expression that is not a "function call, method
call or communication operation" has an undefined order of evaluation,
including (as the later paragraph clarifies) index expressions.

Consider for example:

https://play.golang.org/p/xGaEDjTuzw

To my understanding, it is undefined when "j-1" evaluates, hence that code
_might_ panic.

But maybe I read/inferred that incorrectly?

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Expression evaluation with side effects

2017-03-21 Thread Jan Mercl
On Tue, Mar 21, 2017 at 6:11 PM John McKown 
wrote:

> ​Logically yes, but due the implementation, along with "side effects"
(undocumented?), it does. The "x[0]|=foo()" moves x[0] to a temporary area.
It then invokes foo(). It then does the logical or from the "temporary
area" (previous value of x[0]) with the return value from foo(), getting 3.

Yeah, I got it, thanks to you both. Steven pointed me to the part of the
specs I've read hundred times before and few times again before asking on
the ML. The problem was that I repeatedly mentally misread 'indexing' for
'index evaluation'. As the index is a constant in this case, it lead me to
believe it cannot have any effect on the result. But it's the 'indexing',
the actual time when the value is loaded using the index, which is exempt
from the 'left-to-right' evaluation rule for operands.

-- 

-j

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Expression evaluation with side effects

2017-03-21 Thread John McKown
On Sun, Mar 19, 2017 at 6:20 PM, Steven Hartland 
wrote:

> Think the following section should explain the strange behaviour you're
> seeing:
> https://golang.org/ref/spec#Order_of_evaluation
>
> On 19/03/2017 22:59, Jan Mercl wrote:
>
> While trying to resolve a failing (C) test case[0] I encountered a (Go)
> behavior I do not understand. This code[1]
>
> package main
>
> import (
> "fmt"
> )
>
> var (
> x  = [1]int{2}
> x2 = [1]int{2}
> )
>
> func foo() int {
> x[0] |= 128
> return 1
> }
>
> func foo2() int {
> x2[0] |= 128
> return 1
> }
>
> func main() {
> x[0] |= foo()
> fmt.Println(x[0])
> v := x2[0] | foo2()
> fmt.Println(v)
> }
>
> outputs:
>
> 3
> 131
>
> It seems to me that the two numbers should be the same. (?)
>
> ​Logically yes, but due the implementation, along with "side effects"
(undocumented?), it does. The "x[0]|=foo()" moves x[0] to a temporary area.
It then invokes foo(). It then does the logical or from the "temporary
area" (previous value of x[0]) with the return value from foo(), getting 3.

v:= x2[0] | foo2() does compiles (on x86_64 at least) to : call foo2();
fetch the value of x2[0]; logically or it with the result from foo2();​
store the result back into x2[0].

WHY does it generate the code this way? I have only the vaguest idea. I'm
not a compiler writer. And I can't seem to find the documentation on
exactly how "|=" works. I'm also not an Intel x86_64 assembler programmer,
but I can get a general understanding of what is going on.

>
> Thanks in advance to anyone enlightening me.
>
>   [0]: https://github.com/gcc-mirror/gcc/blob/
> 4107202e2b8f814f4c63a61b043cfb36a3798de3/gcc/testsuite/gcc.
> c-torture/execute/pr58943.c
>   [1]: https://play.golang.org/p/fGibPFuejQ
>
> --
>
> -j
>
>
-- 
"Irrigation of the land with seawater desalinated by fusion power is
ancient. It's called 'rain'." -- Michael McClary, in alt.fusion

Maranatha! <><
John McKown

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Expression evaluation with side effects

2017-03-19 Thread Steven Hartland
Think the following section should explain the strange behaviour you're 
seeing:

https://golang.org/ref/spec#Order_of_evaluation

On 19/03/2017 22:59, Jan Mercl wrote:
While trying to resolve a failing (C) test case[0] I encountered a 
(Go) behavior I do not understand. This code[1]


package main
import (
"fmt"
)
var (
x  = [1]int{2}
x2 = [1]int{2}
)
func foo() int {
x[0] |= 128
return 1
}
func foo2() int {
x2[0] |= 128
return 1
}
func main() {
x[0] |= foo()
fmt.Println(x[0])
v := x2[0] | foo2()
fmt.Println(v)
}
outputs:

3
131

It seems to me that the two numbers should be the same. (?)

Thanks in advance to anyone enlightening me.

  [0]: 
https://github.com/gcc-mirror/gcc/blob/4107202e2b8f814f4c63a61b043cfb36a3798de3/gcc/testsuite/gcc.c-torture/execute/pr58943.c

  [1]: https://play.golang.org/p/fGibPFuejQ

--

-j

--
You received this message because you are subscribed to the Google 
Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send 
an email to golang-nuts+unsubscr...@googlegroups.com 
.

For more options, visit https://groups.google.com/d/optout.


--
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Expression evaluation with side effects

2017-03-19 Thread Jan Mercl
While trying to resolve a failing (C) test case[0] I encountered a (Go)
behavior I do not understand. This code[1]

package main

import (
"fmt"
)

var (
x  = [1]int{2}
x2 = [1]int{2}
)

func foo() int {
x[0] |= 128
return 1
}

func foo2() int {
x2[0] |= 128
return 1
}

func main() {
x[0] |= foo()
fmt.Println(x[0])
v := x2[0] | foo2()
fmt.Println(v)
}

outputs:

3
131

It seems to me that the two numbers should be the same. (?)

Thanks in advance to anyone enlightening me.

  [0]:
https://github.com/gcc-mirror/gcc/blob/4107202e2b8f814f4c63a61b043cfb36a3798de3/gcc/testsuite/gcc.c-torture/execute/pr58943.c
  [1]: https://play.golang.org/p/fGibPFuejQ

-- 

-j

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.