-
Notifications
You must be signed in to change notification settings - Fork 90
Specify temporary for this
as an input parameter
#927
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
Specify temporary for this
as an input parameter
#927
Conversation
Regarding #894 (comment) and #894 (comment) I don't believe a spec change is needed to prohibit a defensive copy for a |
Regarding #894 (comment) (what about I think this can be something we leave to implementations as an optimization. In the case of roslyn, they may avoid the defensive copy because the compiler "knows" that Without writing contrived code, you can't observe the lack of a defensive copy. Question for the committee: Should we add a note that a specific implementation may be able to avoid the defensive copy when the behavior of a specific method is well known? |
Regarding #894 (comment) Is the I don't think any changes are needed. If |
Regarding #894 (comment) (other 2nd commit updates the restriction to include |
9dafe97
to
9896a8c
Compare
Regarding #894 (comment)
I think the standard does prohibit this via §15.6.2.3 ("It is a compile-time error to modify the value of an input parameter.") A reasonable interpretation of passing a parameter as a |
The final two comments on #894 detail where we could take the strategy of defining a I think the proposed changes fix the issue, and are smaller in scope. |
Regarding #894 (comment) Example: struct S {
public void M() {}
}
class C {
void N(bool b, ref S r, in S i) {
(b ? ref r : ref i).M();
}
} I believe this is covered, but it requires a look at 12.18:
This example highlights why I'm trying to avoid limitations on implementers. This doesn't require a defensive copy of the If a defensive copy were required regardless of the result, a compliant compiler would be forced to create that copy, even when it isn't necessary. The motivation for all the We could make a change to 12.18, but I think the description of |
First commit: Fix the issue raised in the description of dotnet#894: If a method takes an `in` parameter of a struct type that is not a `readonly struct`, then the compiler must create a temporary to invoke a non-readonly member of that type.
9896a8c
to
12f2e79
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of comments, but generally okay.
Can we not say that for all defensive copies? I.e. that a compiler can omit any of them if it knows the defense is not required? Indeed can we not specify that normatively as in “a defensive copy shall be made unless the compiler can determine it is not required”? |
Fixes #894
Issue #894 has several comments that describe different possible concerns. To help reviewers (and to keep my head around each different scenario). Each commit will fix one of the concerns.
The first commit fixes the concern in the description:
If a method takes an
in
parameter of a struct type that is not areadonly struct
, then the compiler creates a temporary to invoke a (non-readonly) member of that type. Note that for C# 8.0, this will need to be revisited again to note that a copy needn't be created to invoke areadonly
member of a non-readonly struct.