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

fmt: %*d is too picky about type of length #10732

Closed
rsc opened this issue May 7, 2015 · 2 comments
Closed

fmt: %*d is too picky about type of length #10732

rsc opened this issue May 7, 2015 · 2 comments
Assignees
Milestone

Comments

@rsc
Copy link
Contributor

@rsc rsc commented May 7, 2015

I am writing a program with a bit buffer and a bit count. For good reasons it makes sense for the count to be something other than int (for example, you're shifting by it a lot, so it makes sense for it to be unsigned).

package main
import "fmt"
func main() {
    var bits uintptr = 5
    var count uintptr = 5
    fmt.Printf("%*b\n", count, bits)
}

prints "%!(BADWIDTH)101". http://play.golang.org/p/BGxyBdPV5E

It seems like maybe fmt should allow any integer type for the width. It's a tiny bit more effort in the code and it eliminates an annoyance for users. In my case I didn't know what BADWIDTH meant and at first thought the value was actually bad in some way. It was only when I was about to read the docs that I realized the problem was likely the type.

@robpike

@robpike robpike self-assigned this May 7, 2015
@robpike robpike added this to the Go1.5 milestone May 7, 2015
@robpike
Copy link
Contributor

@robpike robpike commented May 7, 2015

Don't know how to fix this without adding an allocation to every print. I tried the obvious thing and the test failed:

fmt_test.go:961: Sprintf("%x"): got 3 allocs, want <=2

etc. I believe the problem is that the arrival of reflection causes the argument to escape.

Before the change, given Printf("%x", 3):

go tool 6g -m x.go
x.go:6: 3 escapes to heap
x.go:6: main ... argument does not escape

After the change:

dunnart=% go tool 6g -m x.go
x.go:6: ... argument escapes to heap
x.go:6: 3 escapes to heap

Without reflection there is no way to handle every integer type. I could handle int and uint but that seems unsatisfactory.

@robpike robpike modified the milestones: Unplanned, Go1.5 Jun 2, 2015
@robpike
Copy link
Contributor

@robpike robpike commented Aug 5, 2015

Update: This now works without allocation:
v := reflect.ValueOf(a[argNum])
switch v.Kind() {
case reflect.Int:
isInt = true
num = int(v.Int())
}
so we are clear to fix this. Not sure what changed, if anything. Adding to 1.6.

@robpike robpike modified the milestones: Go1.6, Unplanned Aug 5, 2015
@robpike robpike closed this in a00cec9 Sep 10, 2015
@golang golang locked and limited conversation to collaborators Sep 22, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.