-
Notifications
You must be signed in to change notification settings - Fork 87
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
Create general by-reference clause #1028
Create general by-reference clause #1028
Conversation
Fixes dotnet#799 There are several declarations that are duplicated, or triplicated in the description of `in`, `out`, and `ref` parameters. This PR pushes those into a common section on "by-reference parameters". Each subsequent section describes the particular keyword.
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.
Adding comments for reviewers because the diffs aren't as useful as I'd hoped.
|
||
When a formal parameter is an input parameter, the corresponding argument in a method invocation shall consist of either the keyword `in` followed by a *variable_reference* ([§9.2.8](variables.md#928-input-parameters)) of the same type as the formal parameter, or an *expression* for which an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) exists from that argument expression to the type of the corresponding parameter. A variable shall be definitely assigned before it can be passed as an input parameter. | ||
> *Note*: The referent of a by-reference parameter can be changed using the ref assignment (`= ref`) operator. |
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.
This note was only in the in
and ref
sections. However, it applies to out
parameters as well.
It is a compile-time error to modify the value of an input parameter. | ||
|
||
Within a method, an input parameter is always considered definitely assigned. | ||
When a formal parameter is a by-reference parameter, the corresponding argument in a method invocation shall consist of the corresponding keyword, `in`, `ref`, or `out`, followed by a *variable_reference* ([§9.5](variables.md#95-variable-references)) of the same type as the formal parameter. However, when the formal parameter is an `in` parameter, the argument may be an *expression* for which an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) exists from that argument expression to the type of the corresponding parameter. |
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.
This paragraph was almost identical in all sub-clauses. I propose this edit, where the exception for in
is declared in the general clause. An alternative would be to keep the (almost) triplicate code in each of the three sub-clauses.
In a method that takes input parameters, it is possible for multiple names to represent the same storage location. | ||
|
||
> *Note*: The primary purpose of input parameters is for efficiency. When the type of a method parameter is a large struct (in terms of memory requirements), it is useful to be able to avoid copying the whole value of the argument when calling the method. Input parameters allow methods to refer to existing values in memory, while providing protection against unwanted changes to those values. *end note* | ||
In a method that takes multiple by-reference parameters, it is possible for multiple names to represent the same storage location. |
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.
This was interesting. The original text disallowed in
on iterators and async methods. For ref
, only iterators were disallowed (incorrect: ref
is disallowed for async). For out
parameters, it was only disallowed for iterators and partial
methods. The statement on partial
methods is now in the section for out
, and the other restrictions are here.
A method declared as a partial method ([§15.6.9](classes.md#1569-partial-methods)) or an iterator ([§15.14](classes.md#1514-iterators)) may not have output parameters. | ||
|
||
Output parameters are typically used in methods that produce multiple return values. | ||
> *Note: Output parameters are typically used in methods that produce multiple return values. *end note* |
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.
This was normative in the existing draft. I don't think it's required to be normative, so I made this a note.
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.
Agreed, anything with "typically" shouldn't be normative.
standard/classes.md
Outdated
|
||
A parameter declared with a `ref` modifier is a reference parameter. A reference parameter is a local reference variable ([§9.7](variables.md#97-reference-variables-and-returns)) that gets its initial referent from the corresponding argument supplied in the method invocation. | ||
A parameter declared with an `in` modifier is a input parameter. The argument corresponding to an `in` parameter is either a variable existing at the point of the method invocation, or one created by the implementation ([§12.6.2.3](expressions.md#12623-run-time-evaluation-of-argument-lists)) in the method invocation. A variable shall be definitely assigned before it can be passed as an input parameter. Within a method, an input parameter is always considered definitely assigned. |
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.
The rules on definite assignments have the "2 out of 3" problem. The rules for in
and ref
are identical: The variable representing the argument must be definitely assigned before using it as an argument, and the parameter is considered definitely assigned in the entirety of the method. The rules for out
are different. Here, I chose to keep the three distinct copies. I think it read better.
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.
I've looked at the new text more than the change (as you noted the diffs weren't helpful). A couple of suggestions, but otherwise looks good as a reconciliation.
Would be good to get feedback from others as well though.
A method declared as a partial method ([§15.6.9](classes.md#1569-partial-methods)) or an iterator ([§15.14](classes.md#1514-iterators)) may not have output parameters. | ||
|
||
Output parameters are typically used in methods that produce multiple return values. | ||
> *Note: Output parameters are typically used in methods that produce multiple return values. *end note* |
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.
Agreed, anything with "typically" shouldn't be normative.
Co-authored-by: Jon Skeet <skeet@pobox.com>
Co-authored-by: Jon Skeet <skeet@pobox.com>
Fixes #799
There are several declarations that are duplicated, or triplicated in the description of
in
,out
, andref
parameters.This PR pushes those into a common section on "by-reference parameters". Each subsequent section describes the particular keyword.
The diffs are less helpful than I'd hoped, so I've annotated the changes to make reviews easier.