Skip to content

Strange behaviour with loops #45175

@crone123

Description

@crone123

What version of Go are you using (go version)?

$ go version
go version go1.16.2 darwin/amd64

(same problem on linux)

Does this issue reproduce with the latest release?

This is the latest release, I mean

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/vcrone/Library/Caches/go-build"
GOENV="/Users/vcrone/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/vcrone/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/vcrone/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/Users/vcrone/sdk/go1.16.2"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/Users/vcrone/sdk/go1.16.2/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.16.2"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/3b/4rpn6rr54vn1qbqdwvgrv3f80000gn/T/go-build1088450240=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

If you run this code:

func sqrt(x float64) float64 {
	var r float64 = 1
	var old = x
	var first = true
	for first || math.Abs(old - r) > 0.00001 {
		first = false
		old = r
		r -= (r*r - x) / (2*r)
		println("First print")
		println(r)
		println(old)
		println("Second print")
		println(r, old )// This line
		println(r)
		println(old)
	}
	return r
}

Remove this line println(r,old)and the loop fail.

What did you expect to see?

First print
+1.500000e+000
+1.000000e+000
Second print
+1.500000e+000 +1.000000e+000
+1.500000e+000
+1.000000e+000
First print
+1.416667e+000
+1.500000e+000
Second print
+1.416667e+000 +1.500000e+000
+1.416667e+000
+1.500000e+000
First print
+1.414216e+000
+1.416667e+000
Second print
+1.414216e+000 +1.416667e+000
+1.414216e+000
+1.416667e+000
First print
+1.414214e+000
+1.414216e+000
Second print
+1.414214e+000 +1.414216e+000
+1.414214e+000
+1.414216e+000
+1.414214e+000

What did you see instead?

First print
+1.500000e+000
+1.000000e+000
Second print
+1.500000e+000
+1.000000e+000
+1.500000e+000

Additional notes

If I run the same code without optimisations:

go run -gcflags '-N -l' main.go

It works as expected.

Compiler bug?
If this is not a compiler bug, can you explain me what is the problem? Why removing a println cause a total behaviour change?

Thank you

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions