csharplang/meetings/2022/LDM-2022-02-07.md

4.2 KiB

C# Language Design Meeting for February 7th, 2022

Agenda

  1. Detailed review of https://github.com/dotnet/csharplang/blob/main/proposals/checked-user-defined-operators.md (AlekseyTs)

Checked user-defined operators

https://github.com/dotnet/csharplang/blob/main/proposals/checked-user-defined-operators.md

Syntax

We discussed a few syntax options:

  1. checked after operator
  2. put checked before operator
  3. use checked modifier

Conclusion: Stick with proposed syntax (option 1, checked after operator).
PS: it will be nice for implementation to gracefully handle invalid combinations, like checked +.

Checked implicit conversions?

We clarified why conversions cannot be implicit and checked. Generally, implicit conversions should not fail, throw or be lossy. That's already the case with (most) existing conversions and .NET guidelines. There's an exception: integer to floating point conversion in C# does allow loss.

Conclusion: Stick with proposed restriction (conversions cannot be implicit and checked).

Explicitly unchecked operators

The proposal is that there are regular operators (without a keyword) and checked operators (with checked keyword), but there is no keyword like unchecked to express the "no keyword" default. In some other discussions, we have have allowed a keyword to make the default explicit, but it doesn't feel that useful here. Legacy operators don't exactly have the unchecked meaning.

Conclusion: No explicitly unchecked operator (whether semantically equivalent to regular operators or some other meaning).

Restricting allowed combinations of declared operators?

Should there be some requirements on having both operators when a checked operator is declared?

What combinations do we allow? 0. provide none

  1. provide both
  2. provide only regular/unchecked
  3. provide only checked

The only combination we could consider restricting is (3). But that seems a valid case when you don't know what to do for overflow. There's a question whether should declare a regular operator in such case.

Conclusion: No requirement. We may revise this after follow-up discussion on overload resolution rules.

Is the body of a checked operator in checked context?

There's a risk users would assume that checked keyword affects context in method body. But we feel users are likely to want to implement their own checks and use unchecked logic in the body, and we don't want such cases to require use of unchecked:

operator checked ++(...)
{
    unchecked { ... }
    _ = unchecked(...);
}

For example, some types like uint128 need some checked and some unchecked logic in their checked operators:

result.lower = left.lower + right.lower; // overflow is expected/by-design
result.upper = left.upper + right.upper; // overflow is an exception for checked operator

We considered some possible rules for producing a warning. For example: a checked operator must has an checked or unchecked block/context.

Conclusion: No warning in the language. We encourage analyzer or IDE help. Can be revised based on feedback.

Names in metadata

Proposal API names seem straightforward but should be reviewed through API review. op_UnsignedRightShift already establishes precedent on naming schema.

Overload resolution

We reviewed the alternatives listed in the proposal doc, and explored some variants. It's not obvious that we should favor a checked operator on base type over an unchecked/regular operator on closer type, in a checked context. It's not obvious whether the rules should be symmetric (checked picked first in checked context, unchecked/regular picked first in unchecked context) or asymmetric (checked operator can only be picked in checked context). We discussed how to represent a type with only a checked operator. Should that literally be a checked operator, or rather a regular operator?

The main alternative proposal we explored:

  1. lookup would find the nearest applicable candidate (checked operator only applicable in checked context, regular operator applicable in either context)
  2. in checked context, if there's any checked candidates, discard the unchecked ones

Conclusion: proposal will be spelled out and re-discussed in LDM.