-
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]: Checked Operators #4665
Comments
CC. @MadsTorgersen, @AlekseyTs, @stephentoub 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. |
#686 should be closed once this is championed. |
Should it be the other way around, that a user could optionally implement an And obviously, this could lead to breaking changes if a BCL type implemented a different checked/unchecked operator on an existing type. |
The proposal here has
|
I think that instead of using |
|
My reasoning for disliking the naked I agree with needing the naked |
Another advantage of having |
The main issue is trying to fit this onto 20 years of existing types. In the majority scenario, Today we have Having While if its expected instead that |
There is nothing saying that If this was on a common interface ( Some types (like |
If there was no way to differentiate between checked and unchecked operators before, why would people assume operator + was checked? |
I was thinking that the expression
So, for example: // /checked+
var x = 1 + 2; // Binds to op_AdditionChecked (checked mode is on, no explicit scope)
var y = checked(1 + 2); // Binds to op_AdditionChecked (checked mode is on, explicit scope)
var z = unchecked(1 + 2); // Binds to op_AdditionUnchecked (checked mode is on, explicit scope)
var w = delegate { } + delegate { }; // Binds to op_Addition (Delegate doesn't declare checked-ness, as it is unimportant)
// /checked-
var x = 1 + 2; // Binds to op_AdditionUnchecked (checked mode is off, no explicit scope)
var y = checked(1 + 2); // Binds to op_AdditionChecked (checked mode is off, explicit scope)
var z = unchecked(1 + 2); // Binds to op_AdditionUnchecked (checked mode is off, explicit scope)
var w = delegate { } + delegate { }; // Binds to op_Addition (Delegate doesn't declare checked-ness, as it is unimportant) |
That's the problem; because there was no way to differentiate, some people chose to implement them as checked, while others chose to implement them as unchecked. Consumers of these types would expect the behaviour of their code to remain the same, even if the original type decided to expose checked/unchecked operators. As such, changing the meaning of |
I think its worth expanding this table a bit more. Today we have: // /checked+, op_Addition defined
var x = 1 + 2; // Binds to op_Addition (checked mode is on, no explicit scope)
var y = checked(1 + 2); // Binds to op_Addition (checked mode is on, explicit scope)
var z = unchecked(1 + 2); // Binds to op_Addition (checked mode is on, explicit scope)
// /checked-, op_Addition defined
var x = 1 + 2; // Binds to op_Addition (checked mode is off, no explicit scope)
var y = checked(1 + 2); // Binds to op_Addition (checked mode is off, explicit scope)
var z = unchecked(1 + 2); // Binds to op_Addition (checked mode is off, explicit scope) This proposal adds: // /checked+, op_Addition defined, op_AdditionChecked defined
var x = 1 + 2; // Binds to op_AdditionChecked (checked mode is on, no explicit scope)
var y = checked(1 + 2); // Binds to op_AdditionChecked (checked mode is on, explicit scope)
var z = unchecked(1 + 2); // Binds to op_Addition (checked mode is on, explicit scope)
// /checked-, op_Addition defined, op_AdditionChecked defined
var x = 1 + 2; // Binds to op_Addition (checked mode is off, no explicit scope)
var y = checked(1 + 2); // Binds to op_AdditionChecked (checked mode is off, explicit scope)
var z = unchecked(1 + 2); // Binds to op_Addition (checked mode is off, explicit scope) This means:
You are proposing to also have: // /checked+, op_Addition defined, op_AdditionUnchecked defined
var x = 1 + 2; // Binds to op_Addition (checked mode is on, no explicit scope)
var y = checked(1 + 2); // Binds to op_Addition (checked mode is on, explicit scope)
var z = unchecked(1 + 2); // Binds to op_AdditionUnchecked (checked mode is on, explicit scope)
// /checked-, op_Addition defined, op_AdditionUnchecked defined
var x = 1 + 2; // Binds to op_AdditionUnchecked (checked mode is off, no explicit scope)
var y = checked(1 + 2); // Binds to op_Addition (checked mode is off, explicit scope)
var z = unchecked(1 + 2); // Binds to op_AdditionUnchecked (checked mode is off, explicit scope)
// /checked+, op_Addition defined, op_AdditionChecked defined, op_AdditionUnchecked defined
var x = 1 + 2; // Binds to op_AdditionChecked (checked mode is on, no explicit scope)
var y = checked(1 + 2); // Binds to op_AdditionChecked (checked mode is on, explicit scope)
var z = unchecked(1 + 2); // Binds to op_AdditionUnchecked (checked mode is on, explicit scope)
// /checked-, op_Addition defined, op_AdditionChecked defined,, op_AdditionUnchecked defined
var x = 1 + 2; // Binds to op_AdditionUnchecked (checked mode is off, no explicit scope)
var y = checked(1 + 2); // Binds to op_AdditionChecked (checked mode is off, explicit scope)
var z = unchecked(1 + 2); // Binds to op_AdditionUnchecked (checked mode is off, explicit scope) For the case where
For the case where
Based on the compiler defaults, I believe just having
|
Is this going to be supported with |
But this means depending on the compiler switch the checked operator and the regular could become the same but with different implementations. Which one is used then? Or do I miss something? |
That's under the "open questions". My suggestion is that if This would hopefully help keep things simple "overall" while maintaining compat and helping with correctness. |
@tannergooding: That makes sense. Thanks for commenting on this. |
Would it make sense instead of having two separate operator methods (checked/unchecked) just add some option for the operator method to know if context is checked or unchecked? For example additional method parameter or some static property that might be useful outside of the operator method also? |
I've removed the specification from the issue text and have linked to the checked-in version. |
If adding metadata names for checked operators to ECMA-335, would it make sense to add matching assignment operators as well (e.g. In fact, given that in the case of right shifts, ECMA-335 had |
ECMA-335 itself doesn't define checked behavior for As for |
I only gave the shifts as an example of ECMA-335 defining metadata names for variants (signed and unsigned) despite C#/VB/... only using the regular one (until recently). I'm merely suggesting that if the concept of checked arithmetic operators is added, it might make sense to do so in a similarly comprehensive way. So you'd have |
It is explicit that there is no "unchecked" variant. The design is such that if only Once |
Implemented |
Does it make sense to mark somehow (i.e. keep updated) this status in starting message? |
Checked Operators
Specification
https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/checked-user-defined-operators.md
Design meetings
The text was updated successfully, but these errors were encountered: