-
Notifications
You must be signed in to change notification settings - Fork 1k
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]: Relaxing shift operator requirements #4666
Comments
The right hand side could be restricted to be some That being said, nothing is restricting a user from defining Additionally, the language will already consume operators (such as defined in IL) where the second operator is not |
CC. @MadsTorgersen, @AlekseyTs, @stephentoub Same here. Please let me know if you believe anything from the meeting was not covered here or if there are any additional changes or clarifications that I can make to the proposal. |
Hm, I could not get the following code to compile on sharplab: using System.Runtime.CompilerServices;
using System;
C x = new();
x = x << 3;
// ^^^^^^ error CS0019: Operator '<<' cannot be applied to operands of type 'C' and 'int'
class C
{
[SpecialName]
public static C op_LeftShift(C c, object o)
{
Console.WriteLine("shift operator called with " + o);
return c;
}
} Am I missing something? |
It cannot be within a single assembly, it must be across two separate assemblies That is, if assembly |
Ahh, I see. Thanks for clearing that one up! |
The only alternatives I see mentioned are workarounds for not changing the language at all. Has a lesser feature been considered where the restriction is only partially relaxed? For example, rather than removing restrictions on the type of the second operand entirely, the restriction could be relaxed to "any primitive integer type or the type containing the operator declaration". I think this would fulfil the needs of the generic math interfaces while preserving the intent behind the original restriction. |
This would not work for any integer type that wasn't a primitive. For example, say you want to be shiftable by |
I can't imagine a use case for that except when the type being shifted is the same type. Within the struct CustomInt
{
public static CustomInt operator <<(CustomInt a, Int128 b);
} |
The amount of work required to restrict it is likely more than the amount of work required to simply remove the restriction. Users can always misuse features. You can define a Most users (and particularly the most popular libraries) will not however. And even if C# did restrict what it could define, it already accepts and utilizes the operators some other language may define that don't follow its own rules. So it remains an artificial restriction in what C# can define vs what C# will actually consume from IL. |
Fair enough. Just wanted to see that it has been considered. |
Feature was merged into 17.3p2 |
@MadsTorgersen / @tannergooding Can this issue be closed now? |
Issues on csharplang tend to stay open for some time after they have been implemented and shipped. I'd expect the proposal champion will close it as appropriate for the C# LDM needs. |
@333fred : could you update the check marks for how far along it is? |
Done. |
Relaxing shift operator requirements
Summary
The shift operator requirements will be relaxed so that the right-hand side operator is no longer restricted to only be
int
.Motivation
When working with types other than
int
, it is not uncommon that you shift using the result of another computation, such as shifting based on theleading zero count
. The natural type of something like aleading zero count
is the same as the input type (TSelf
) and so in many cases, this requires you to convert that result toint
before shifting, even if that result is already within range.Within the context of the generic math interfaces the libraries are planning to expose, this is potentially problematic as the type is not well known and so the conversion to
int
may not be possible or even well-defined.Detailed design
https://github.com/dotnet/csharplang/blob/main/spec/expressions.md#shift-operators should be reworded as follows:
That is, the restriction that the first operand be the class or struct containing the operator declaration remains. While the restriction that the second operand must be
int
is removed.Drawbacks
Users will be able to define operators that do not follow the recommended guidelines, such as implementing
cout << "string"
in C#.Alternatives
The generic math interfaces being exposed by the libraries could expose explicitly named methods instead. This may make code more difficult to read/maintain.
The generic math interfaces could require the shift take
int
and that a conversion be performed. This conversion may be expensive or may be not possible depending on the type in question.Unresolved questions
Is there concern around preserving the "intent" around why the second operand was restricted to
int
?Design meetings
The text was updated successfully, but these errors were encountered: