-
Notifications
You must be signed in to change notification settings - Fork 18k
cmd/vet, x/tools/go/analysis: flag superfluous fmt.Errorf (without format specifiers) calls to instead use errors.New and save binary size #52696
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
Comments
Since this is an efficiency issue and not a correctness one, vet is not the place to address this, but doing the check in another tool - or just grepping, as you point out - would be a fine solution. |
…w if needed Implements a CLI tool that'll traverse a directory, find all patterns matching fmt.Errorf without format specifiers and replace in-place such with errors.New. For example for the Go standard library ```shell go run main.go $GOPATH/src/go.googlesource.com ``` Updates golang/go#52696
…w if needed Implements a CLI tool that'll traverse a directory, find all patterns matching fmt.Errorf without format specifiers and replace in-place such with errors.New. For example for the Go standard library ```shell go run main.go $GOPATH/src/go.googlesource.com ``` Updates golang/go#52696
Change https://go.dev/cl/403938 mentions this issue: |
Change https://go.dev/cl/403955 mentions this issue: |
I did write such a tool indeed at https://github.com/orijtech/otils/blob/master/fmterrorffix/main.go to find and replace the patterns. However, @robpike the problem with not adding this pass to the standard Go tool chain is that letting our users actually invoke |
Isn't the increased binary size only due to importing I've seen cases where We should at least not flag cases where it doesn't matter imo, it feels more like an opinion than something that actually makes a difference. |
related; #6853 |
Thanks for raising the issue, but please don't do this. Using fmt.Errorf("foo") is completely fine, especially in a program where all the errors are constructed with fmt.Errorf. Having to mentally switch between two functions based on the argument is unnecessary noise. Vet is for important correctness errors. fmt.Errorf("foo") is correct as is. If you want to proceed with this vet change, it should be a proposal, but it's unlikely to be accepted. |
The binary size change is dramatic only because this is a trivial program that does nothing at all. So deleting the one reference to fmt let the binary not link fmt at all. But any real program is already linking in fmt because of one library or another. Removing a single call to fmt.Errorf in such a program will have no appreciable effect on binary size. |
This was also discussed, but not for long, as #17173. |
As others have pointed out, this is not actually an inefficiency in practice since every program links in the fmt package. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?Not applicable
What did you do?
Per https://twitter.com/odeke_et/status/1520929877104332801, over the weekend while working on some code for an embedded system, I examined the binary size and noticed the use of fmt.Errorf without format specifiers or just constant strings was permitted and could instead use errors.New of which the results of swapping the change caused a 600KiB reduction in binary size on Linux AMD64, and 700KiB reduction in binary size on Darwin AMD64!
Just compiled this simple program https://go.dev/play/p/Ec6Wy1sUpF_e or inlined below
On Linux it results in a 1.8MiB binary on both Linux AMD64 and Darwin AMD64
go build -o fmt-binary main.go && ls -lh -rwxrwxr-x 1 emmanuel emmanuel 1.8M May 1 17:41 fmt-binary
On changing it to use errors.New
results in a 1.2MiB binary on Linux AMD64 and a 1.1MiB binary on Darwin AMD64
What did you expect to see?
Running
go vet
orgo test
should flag such calls and make suggestions. I expected thisfmt.Errorf has no formatting directives, please instead use "errors.New"
What did you see instead?
Importing the fmt package unnecessarily results in that bloat, and we should do our best to avoid this problem. Unfortunately even our standard library has 374 such superfluous calls if I run
with the results in the depressible details below
At Orijtech Inc we've got a patch to add this functionality for Go1.19
The text was updated successfully, but these errors were encountered: