Skip to content

proposal: embed "noCopy" for bytes.Buffer and strings.Builder #25907

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

Closed
dotaheor opened this issue Jun 15, 2018 · 10 comments
Closed

proposal: embed "noCopy" for bytes.Buffer and strings.Builder #25907

dotaheor opened this issue Jun 15, 2018 · 10 comments

Comments

@dotaheor
Copy link

Some new gophers may make mistakes by copying bytes.Buffer and strings.Builder values.
Embed a noCopy will let vet find such mistakes.

@gopherbot gopherbot added this to the Proposal milestone Jun 15, 2018
@dsnet
Copy link
Member

dsnet commented Jun 15, 2018

Unfortunately, that will give the bytes.Buffer and strings.Builder types a Lock method. I think we need a cleaner way to tell the vet something is not copy-able.

@ianlancetaylor
Copy link
Contributor

Note that strings.Builder already has a dynamic no-copy check.

@dotaheor
Copy link
Author

dotaheor commented Jun 16, 2018

@dsnet sorry, my mistake, the noCopy should be non-anonymous so that its methods will not be exported. Just like what sync.WaitGroup does.

@ianlancetaylor I didn't notice that strings.Builder has a dynamic no-copy check. But it looks the dynamic check doesn't work for some situations, and it increases the run-time burden.

@dsnet
Copy link
Member

dsnet commented Jun 17, 2018

But it looks the dynamic check doesn't work for some situations, and it increases the run-time burden.

In what cases does it not work? Even if we add noCopy to strings.Builder, we would still want the dynamic check since vet is not run as part of the normal build process. Otherwise strings.Builder would provide too easy a way to accidentally (or even deliberately) step outside Go type safety.

@dotaheor
Copy link
Author

dotaheor commented Jun 18, 2018

If a Builder is copied before it writes anything, then the dynamic check doesn't work.

On the other hand, I don't understand what safety the dynamic check guarantees. I couldn't imagine any type unsafety caused by copying a Builder. It looks there are only some unexpected results from the String method calls.

@ianlancetaylor
Copy link
Contributor

It's OK to copy a strings.Builder before writing anything, in the sense that both copies will work correctly.

The dynamic check is there to ensure that the String method returns a value that can not be modified by calls to the Write method in a copy of the Builder. In general lots of code assumes that Go strings can not be modified.

@ianlancetaylor
Copy link
Contributor

Actually adding a Lock method does not sound like a good idea, as @dsnet mentioned above.

As described in cmd/vet/README, vet checks should be for problems that are correctness errors, frequent, and where the vet check can be precise. I guess that a small bytes.Buffer could have a correctness issue, in that there could be unanticipated aliasing of the small buffer. And a proper check could be precise. But I'm not sure this is a frequent problem.

@dotaheor
Copy link
Author

dotaheor commented Jun 19, 2018

OK, get it.

How about change the type of the Builder.buf field to *[]byte? So that we the dynamic check is not needed any more.

@ianlancetaylor
Copy link
Contributor

Using a pointer instead of a slice would normally require an additional allocation, which would be unfortunate.

@dotaheor
Copy link
Author

dotaheor commented Jun 20, 2018

Yes, changing the field to a pointer also hurts the performance.
Thanks for the discussion.

Looks this issue is not very valuable, so I will close it.

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

4 participants