-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
proposal: spec: shorthand for named return #59491
Comments
It seems to me that |
@ianlancetaylor I expected this to be true at the beginning, but wrote benchmark tests to verify that assumption out of curiosity. The benchmark results showed that when If the compiler is designed to see |
Since most people generally seem to agree that naked returns are usually a bad practice, I'm not sure if allowing a partial naked return is a good idea. If the problem is a performance regression between |
When two different pieces of code that should perform exactly the same turn out to perform differently, that should be addressed in the compiler. It should not be addressed by changing the language. |
Well I wasn't sure that they should perform exactly the same (as it wasn't an easily google-ed documented behavior, or I missed something). And if they should, then it is a compiler issue (the original title had cmd/compile in it before it got changed). I wasn't familiar with these details to skip the "language change" part at first. |
Based on the discussion above, we are not going to change the language in this way. Therefore, this is a likely decline. Leaving open for three weeks for final comments. |
In the original example: func f() (i, j int) {
i++
return i, 1
} ...there is no explicit definition of func f() (i, j int) {
return 1, 1
} And indeed, that seems to be what the compiler seems to generate:
I also tried this variant: func f(q int) (i, j int) {
i = q
i++
return i, 1
}
This time the compiler noticed that the first argument and the first return value both belong in AX and so optimized it to just incrementing that register directly. It then assigned immediate 1 to the second return value. Perhaps I'm being too easy on the compiler by using a type that fits neatly into a single machine register... func f(q [1000]int) (i [1000]int, j int) {
i = q
q[1]++
return i, 1
}
I don't actually know the expected Go ABI for passing an array as a argument or as a return value, so this one's a bit harder for me to follow. From a brief read of the internal ABI docs I'm inferring that this If I'm reading the above correctly (which I might not be, since I am admittedly rusty on x86 assembly) I think it is directly modifying the array on the stack and then returning, without copying the array. It seems that the compiler has again found the optimization opportunity. To complete the matrix of whether the value originates as an argument on one side and whether the value is a large aggregate on the other side, one more example: func f() (i [1000]int, j int) {
i[1]++
return i, 1
}
Again the array is allocated on the stack. Again the compiler has noticed that From earlier discussion I see that this is likely to be closed due to this not needing a language change, and instead being a potential optimizer improvement. But I also am having trouble finding a situation where the optimizer isn't already succeeding, so if this were to be turned into a suggestion to improve the optimizer I think it would help to share the exact benchmark code that illustrates the problem, so it's clearer what the optimizer improvement would be. |
No change in consensus. |
Suppose we could write:
which is equivalent to:
Currently, if one wants to replace
j = 1; return
with a one line return statement, he could writeBut these are not equivalent except for the outcomes (see this StackOverflow question), And I'm not sure if this kind of "hack" should be discouraged.
The text was updated successfully, but these errors were encountered: