CS8156 generated for temporary "in" parameters when specifying modifier at callsite #1215
Replies: 11 comments
-
Its a compiler (Roslyn) issue if its supposed to work and instead is generating an error. Its a language issue if it was designed not to work, but you think it should. |
Beta Was this translation helpful? Give feedback.
-
In either case I'm not entirely sure which it is then. None of the documentation demonstrates actually using the |
Beta Was this translation helpful? Give feedback.
-
@VSadov and @OmarTawfik should be able to comment as to whether it is a language or compiler issue. |
Beta Was this translation helpful? Give feedback.
-
“in” at call site guarantees that a direct reference to the actual argument is passed without making copies or temporaries. That is not possible with literals, thus “in 3” is an error. |
Beta Was this translation helpful? Give feedback.
-
So from that, this is something that should be clarified more in the docs. |
Beta Was this translation helpful? Give feedback.
-
@VSadov isn't that the point of the modifier in the method signature? Why allow it at all at the call site if it's going to be inconsistent? I would think specifying at the call site works more towards documenting the code than anything-- or are you saying that the code is/should exhibit different behavior in the several different scenarios listed above? |
Beta Was this translation helpful? Give feedback.
-
@pinkfloydx33 The feature of |
Beta Was this translation helpful? Give feedback.
-
“When you add the “in” modifier to pass an argument by reference, you declare your design intent is to pass arguments by reference to avoid unnecessary copying. “ ByVal arguments have the same requirements as they always had. They can match an ordinary byval parameter and may result in copying of the argument when necessary. Some users wanted to be able to ensure that there is no copying. Others see that as optional optimization and wanted compatibility with byval. So - If you want to require that argument is passed by reference, you can add “in”. Similarly to “ref/out” the argument must be an lvalue in such case. void Print<T>(in T arg) {...}
Print(2 + 2); // works
Print(in 2 + 2); // not possible
Print(in Vector3D.UnitX) // works and no copies |
Beta Was this translation helpful? Give feedback.
-
Hmm, so if I have |
Beta Was this translation helpful? Give feedback.
-
@mikedn - yes, that is correct. Such overloads are allowed, but may be difficult to use depending on scenario. You will have to spill a literal value into a temp manually. |
Beta Was this translation helpful? Give feedback.
-
#945 is a somewhat old discussion regarding |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
I'm not sure if this belongs here or in the Rosyln repo; please let me know if I need to report it elsewhere and I will do so happily.
According to this documentation, specifying the
in
modifier at the callsite is not required but should be optional. Indeed, specifying the modifier does work (using the examples from the link above):The documentation also indicates that you should be able to pass a temporary for an
in
parameter. This does work, but when you specify the modifier at the call site, CS8156 is generated:The same may be said for using
default
:In fact, it seems that specifying any literal/constant generates the compiler error if accompanied by the
in
modifier at the call site (yet all work without the modifier):I'm not sure if it's the documentation that is wrong or if there's an issue with the compiler/language with respect to this. Perhaps I'm misunderstanding something. Note that I discovered this just by "playing around" so its possible that I have inadvertently done something I shouldn't have. Regardless, the results seem to be inconsistent with each other and with the documentation.
Beta Was this translation helpful? Give feedback.
All reactions