# 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.