> *tl;dr It will be nice if either the compiler or govet supports informing
> us when an error return value is ignored (ie not used or assigned to
> something, even _).*
The problem is that for some functions it is just fine to ignore errors.
For others it is not. There is no single enforcement policy which fits
all cases. Perhaps there is a good change we can make here. However,
requiring everybody to write
_, _ = fmt.Printf("Hi!")
does not seem to me like a path that Go should follow.
Ian
Some ideas to handle it:
- Pass a compiler flag so that warnings are enabled. Warnings are *only* supported for a few situations where breaking compile is not an option e.g. when ignoring an important return value like error. (if you assign the return value to _, the warning goes away).
- Expand govet to support this. From looking at govet code, this may be harder, since it only looks at static source code one file at a time. However, this seems like the more natural location for this.
> Yes, I agree that having the compiler fail due to this, or requiring
> everyone to assign values to _, is not a good path for GO to follow. I
> appreciate that there's not a quick answer to this.
>
> In my post, I suggested 2 potential ways to handle it.
>
>> Some ideas to handle it:
>> - Pass a compiler flag so that warnings are enabled. Warnings are *only*
>> supported for a few situations where breaking compile is not an option e.g.
>> when ignoring an important return value like error. (if you assign the
>> return value to _, the warning goes away).
>> - Expand govet to support this. From looking at govet code, this may be
>> harder, since it only looks at static source code one file at a time.
>> However, this seems like the more natural location for this.
>
>
> If GO had a policy for warnings, then this would be a good use-case for
> warnings (with some exceptions like fmt.XXX, etc). GO's current policy wrt
> warnings is hard and fast: no warnings.
Right, that is a policy which is simple to implement and easy to
explain.
I personally don't care for either of your ideas, because I don't think
that either of them addresses the problem of
_, _ = fmt.Printf("Hi")
They are both global approaches which apply to all the code in question.
But in the real world, some error returns should almost always be
checked, and some error returns may be checked under some circumstances.
That is, when considering whether to make it a warning/error if error
returns are not checked, you need to consider the function being called,
not just the function doing the calling. Your proposals only consider
the latter.
Compare to gcc's extended C language. There is no way in gcc to say
"check all return values." But there is a way to say "check the return
value of this function" (via __attribute__ ((warn_unused_result))). Of
course even this has its problems, and I don't recommend adopting it
into Go.
Ian
For one thing, someone decided it was a good idea to
tag perfectly reasonable C library calls like write(2) with
the warn_unused_result attribute, which is a royal pain.
I am expecting the next Ubuntu release to tag exit(2).
Russ
Surely it would not be ideal to have to discard return values in cases like this. However, I would trust the Go team to be smarter than to add such annotations onto functions where it is not needed. But there are definitely cases where it is essential that the error be checked.I would suggest to add a keyword or annotation (let's called it "checked" for the purposes of this discussion) in front of the error return part of the function signature, to indicate to the compiler to enforce that an error be received by the caller.The benefit of getting a compiler error for missing error handling on certain important functions by far outweighs the "overhead" imposed on us by some (hopefully few) poorly designed APIs. And actually, if some poorly designed API function turned out to have been incorrectly marked, it would not break an existing code base to remove the checked annotation in a future release.
On Sun, Nov 4, 2012 at 8:29 AM, Hein Meling <hein....@gmail.com> wrote:Surely it would not be ideal to have to discard return values in cases like this. However, I would trust the Go team to be smarter than to add such annotations onto functions where it is not needed. But there are definitely cases where it is essential that the error be checked.I would suggest to add a keyword or annotation (let's called it "checked" for the purposes of this discussion) in front of the error return part of the function signature, to indicate to the compiler to enforce that an error be received by the caller.The benefit of getting a compiler error for missing error handling on certain important functions by far outweighs the "overhead" imposed on us by some (hopefully few) poorly designed APIs. And actually, if some poorly designed API function turned out to have been incorrectly marked, it would not break an existing code base to remove the checked annotation in a future release.Don't do that. The compiler can't make guarantee that the error is correctly handled.
for example, given the gcc warn_unused_result attribute for function f, you can do the followingto trick gcc (-Wall -Wextra compiled without warning):__attribute__((__warn_unused_result__)) int f(int x) { return x * 2; }void g() {__typeof__(f(1)) y;y = f(1);}
However, this surely isn't what the f()'s author expects -- he/she wants the user to act on thereturn value, but this is not the case.
func RegisterChannel(ch interface{}) checked error {
err := RegisterChannel(myCh)Or, to ignore the error (here you are required to use some minor boilerplate to consciously ignore the err):
_ := RegisterChannel(myCh)RegisterChannel(myCh)