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

io: comment for io.Reader confusing for len(p) == 0 #8317

Closed
bcmills opened this issue Jul 2, 2014 · 8 comments
Closed

io: comment for io.Reader confusing for len(p) == 0 #8317

bcmills opened this issue Jul 2, 2014 · 8 comments
Milestone

Comments

@bcmills
Copy link
Contributor

bcmills commented Jul 2, 2014

http://tip.golang.org/pkg/io/#Reader says:

> Implementations of Read are discouraged from returning a zero byte count with a nil
error, and callers should treat that situation as a no-op.


But if len(p) is 0:

> It returns the number of bytes read (0 <= n <= len(p)) and any error
encountered.

implies a return of (0, nil): no bytes were read and no error was encountered, because
it's not an error for the caller to pass in an empty slice.

In practice, Readers in the standard library do return (0, nil) in this situation:
http://play.golang.org/p/b2GLM8FHuH
http://play.golang.org/p/3zJNnttAmq
http://play.golang.org/p/o_Z_1EEGye


The last sentence ("discouraged from returning a zero byte count") should be
changed to read:

> Implementations of Read are discouraged from returning a zero byte count with a nil
error when len(p) > 0, and callers should treat that situation as a no-op.
@ianlancetaylor
Copy link
Contributor

Comment 1:

Labels changed: added repo-main, release-go1.4.

@minux
Copy link
Member

minux commented Jul 2, 2014

Comment 2:

i think making this change will needlessly complicate the docs
without any real benefit.
The docs for Reader doesn't prohibit implementations to return
non-nil error when len(p) == 0, so the suggested rewrite is
still not 100% accurate.
(IMHO, Read(nil) should be treated as a programmer error and get
a non-nil error, if not a panic, because it doesn't do anything
useful and might indicate an error in initializing the argument.)

@bcmills
Copy link
Contributor Author

bcmills commented Jul 2, 2014

Comment 3:

It's not Read(nil) that I'm concerned about.  It's cases like unmarshaling a binary
format with a "length" stamp, where a 0-length is valid and expected.
Consider this program:
var hdr struct{ Length uint32 }
if err := binary.Read(r, binary.BigEndian, &hdr); err != nil {
  return err
}
buf := make([]byte, hdr.Length)
_, err := io.ReadFull(r, buf)
return err
If r.Read([]byte{}) returns a non-nil error, io.ReadFull will spuriously return a
non-nil error as well.
Do you really think it's worth complicating user code in cases like this just to avoid
fixing documentation?

@minux
Copy link
Member

minux commented Jul 2, 2014

Comment 4:

the problem is that the existing docs doesn't guarantee 0-byte
read won't return error, so even if we change the docs now
(note, we can't just add a restriction, as it will be an API
change), you still have to check if length is zero to be sure.
Note: ReadFull won't call the Read method if len(p) is zero,
so your example is safe regardless.
http://play.golang.org/p/Hd-Adrfl_N

@bcmills
Copy link
Contributor Author

bcmills commented Jul 2, 2014

Comment 5:

Well, the other problem is that people see "discouraged from returning a 0-byte count"
and think they need to special-case len(p) == 0 in their own Readers (e.g. stubs used in
testing).
At best, that complicates their implementations for no good reason.

@minux
Copy link
Member

minux commented Jul 2, 2014

Comment 6:

Normally you do need to special case len(p) == 0 otherwise you might
have failed bound checks (for non-trivial Readers).
Also, it's "discouraged", not "prohibited"; and if you think passing
0-byte []byte is not an error, you can return 0, nil as this is your
only choice. (I think they're programmer errors so I will just let
Read panic in this case.)

@gopherbot
Copy link

Comment 7:

CL https://golang.org/cl/143100043 mentions this issue.

@rsc
Copy link
Contributor

rsc commented Sep 16, 2014

Comment 8:

This issue was closed by revision 3d2321f.

Status changed to Fixed.

@rsc rsc added this to the Go1.4 milestone Apr 14, 2015
@rsc rsc removed the release-go1.4 label Apr 14, 2015
@golang golang locked and limited conversation to collaborators Jun 25, 2016
wheatman pushed a commit to wheatman/go-akaros that referenced this issue Jun 25, 2018
Fixes golang#8317.

LGTM=bradfitz
R=bradfitz, iant, r
CC=golang-codereviews
https://golang.org/cl/143100043
wheatman pushed a commit to wheatman/go-akaros that referenced this issue Jul 9, 2018
Fixes golang#8317.

LGTM=bradfitz
R=bradfitz, iant, r
CC=golang-codereviews
https://golang.org/cl/143100043
wheatman pushed a commit to wheatman/go-akaros that referenced this issue Jul 30, 2018
Fixes golang#8317.

LGTM=bradfitz
R=bradfitz, iant, r
CC=golang-codereviews
https://golang.org/cl/143100043
This issue was closed.
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

5 participants