Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

math/big: Unexpected behavior when get a value of *big.Int, call .Add func and return de initial value. #54759

Closed
vinigracindo opened this issue Aug 29, 2022 · 1 comment

Comments

@vinigracindo
Copy link

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

$ go version
go version go1.18.1 darwin/amd64

Does this issue reproduce with the latest release?

yes

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

go env Output
$ go env
GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/vgracindo/Library/Caches/go-build"
GOENV="/Users/vgracindo/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/vgracindo/go/pkg/mod"
GOOS="darwin"
GOPATH="/Users/vgracindo/go"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/opt/go/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/opt/go/libexec/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.18.1"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/vgracindo/workspace/poc/go.mod"
GOWORK=""
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/75/9hndtrr15f9b85q3qmwwvywrwn62nq/T/go-build2606683508=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

  1. Get a copy of a big.int value.
  2. Increment the value attr big.Int of the struct by 1.
  3. Return de copy (1).

For example: https://go.dev/play/p/t0Tw1oDgxIh

What did you expect to see?

package main

import (
	"fmt"
	"math/big"
)

type Anything struct {
	Current *big.Int
}

func (a *Anything) getCurrentAndInc() big.Int {
	current := *a.Current
	a.Current.Add(a.Current, big.NewInt(1))
	return current
}

func main() {
	a := Anything{
		Current: big.NewInt(10),
	}
	current := a.getCurrentAndInc()
	fmt.Println(a.Current.String())
	fmt.Println(current.String())

	current2 := a.getCurrentAndInc()
	fmt.Println(a.Current.String())
	fmt.Println(current2.String())
}

I expect the copy result to be one less than Current after increment.

11 // Current value after increment.
10 // Copy of current value before increment.
12 // Current value after increment.
11 // Copy of current value before increment.

Program exited.

OR

I expect the value of the returned value to always be equal to current (even after increment).

11 // Current value after increment.
11 // Copy of current value before increment.
12 // Current value after increment.
12 // Copy of current value before increment.

Program exited.

What did you see instead?

In the first execution it has a behavior and from the first execution the behavior changes.

11 // Current value after increment.
10 // Copy of current value before increment.
12 // Current value after increment.
12 // Copy of current value before increment.

Program exited.
@randall77
Copy link
Contributor

A big.Int is not meant to be copied shallowly like that. See https://pkg.go.dev/math/big#Int , second paragraph.
Generally you never want a big.Int, only *big.Int.

current := new(big.Int).Set(a) // copies a

Or something like that.

@golang golang locked and limited conversation to collaborators Aug 29, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants