51 lines
2.7 KiB
Markdown
51 lines
2.7 KiB
Markdown
# C# Language Design Notes for Jun 13, 2017
|
|
|
|
## Agenda
|
|
|
|
1. Native-size ints
|
|
2. Native-size floats
|
|
|
|
|
|
# Native-size ints
|
|
|
|
We want `nint` and `nuint` to be part of the language. They will be used in contexts where we care about respecting checked vs unchecked in operator behavior, for example.
|
|
|
|
We have two options for how to represent at runtime:
|
|
|
|
1. Project to `IntPtr`, track the `nint` or `nuint` "overlay" in metadata for compile-time consumption only
|
|
2. Project to new struct types that wrap an `IntPtr` and potentially exhibit different behavior at runtime too
|
|
|
|
Option 2 had some objections attached. Let's go through them:
|
|
|
|
- Adoption/roll out of new types would take time
|
|
- We could embed these struct types in the generated assembly and use the NoPIA machinery to unify them across assemblies.
|
|
- Would have a slight cost on IL size.
|
|
- Probably not a decisive objection
|
|
- Need new overloads for a few things, such as `Interlocked.CompareExchange`
|
|
- We could probably live with those rolling out gradually, especially with access to the `IntPtr` of a `nint` or `nuint` as a public field (so it can be passed by `ref` to existing overloads)
|
|
- There is a bifurcation because the types are really distinct at runtime. There's interop pain between them.
|
|
- This may be a good thing. Arguably they represent different concepts: `IntPtr` is more of an opaque handle, whereas `nint` and `nuint` are real integers with number semantics.
|
|
|
|
Option 1 has some objections as well:
|
|
|
|
- `ToString` doesn't work right
|
|
- This could probably be fixed. It is unlikely that the current deficiencies are depended upon
|
|
- you lose context on box/unbox
|
|
- That is already the case today with other common types, such as tuples, nullable value types and `dynamic`. Is it really so bad?
|
|
- Imprecise reflection info
|
|
- Again, we live with this in many places
|
|
|
|
`String.Format` would exhibit the combination of the first and second problem: passing a `nint` as an argument, it would box and lose context, so `IntPtr.ToString` would get called.
|
|
|
|
Things to ponder regardless of implementation strategy:
|
|
|
|
- **Conversions:** Should there be conversions between `nint`/`nuint` and `IntPtr`? If so, which way (if any) should be implicit?
|
|
- **Upgrade:** Someone using `IntPtr` today might want to switch to `nint`. This would mostly just work, but would have very subtle changes of behavior here and there.
|
|
|
|
## Conclusion
|
|
We are still hung on what to do. We want to more deeply understand objections against Option 1, and understand if mitigations considered would address e.g. Xamarin's concerns.
|
|
|
|
|
|
# Native-size floats
|
|
|
|
Float really is a different discussion. Language embedding is less significant: we don't have a notion of checked/unchecked. The main objective would just be to have an alias. |