diff --git a/standard/conversions.md b/standard/conversions.md index 132a04873..121c53e8d 100644 --- a/standard/conversions.md +++ b/standard/conversions.md @@ -117,8 +117,6 @@ All identity conversions are symmetric. If an identity conversion exists from `T In most cases, an identity conversion has no effect at runtime. However, since floating point operations may be performed at higher precision than prescribed by their type ([§8.3.7](types.md#837-floating-point-types)), assignment of their results may result in a loss of precision, and explicit casts are guaranteed to reduce precision to what is prescribed by the type ([§12.9.8](expressions.md#1298-cast-expressions)). -There is an identity conversion between `nint` and `System.IntPtr`, and between `nuint` and `System.UIntPtr`. - For the compound types array, nullable type, constructed type, and tuple, there is an identity conversion between native integers ([§8.3.6](types.md#836-integral-types)) and their underlying types. ### 10.2.3 Implicit numeric conversions diff --git a/standard/expressions.md b/standard/expressions.md index 2066e33ff..c3ca686df 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -287,6 +287,8 @@ As an example of numeric promotion, consider the predefined implementations of t ```csharp int operator *(int x, int y); uint operator *(uint x, uint y); +nint operator *(nint x, nint y); +nuint operator *(nuint x, nuint y); long operator *(long x, long y); ulong operator *(ulong x, ulong y); float operator *(float x, float y); diff --git a/standard/types.md b/standard/types.md index 4e2e52115..710048d91 100644 --- a/standard/types.md +++ b/standard/types.md @@ -280,7 +280,7 @@ A struct type is a value type that can declare constants, fields, methods, prope ### 8.3.5 Simple types -Except for `nint` and `nuint`, the simple types are aliases for predefined `struct` types in the `System` namespace, as described in the table below. +The simple types are aliases for predefined `struct` types in the `System` namespace, as described in the table below. **Keyword** | **Aliased type** ----------- | ------------------ @@ -290,8 +290,8 @@ Except for `nint` and `nuint`, the simple types are aliases for predefined `stru `ushort` | `System.UInt16` `int` | `System.Int32` `uint` | `System.UInt32` - `nint` | none; see below - `nuint` | none; see below + `nint` | `System.IntPtr` + `nuint` | `System.UIntPtr` `long` | `System.Int64` `ulong` | `System.UInt64` `char` | `System.Char` @@ -300,7 +300,7 @@ Except for `nint` and `nuint`, the simple types are aliases for predefined `stru `bool` | `System.Boolean` `decimal` | `System.Decimal` -Every simple type has members. Each simple type that is an alias for a predefined struct type, has that struct type’s members. +Every simple type has members. Each simple type has its aliased struct type’s members. > *Example*: `int` has any implementation-specific members declared in `System.Int32` and the members (required and implementation specific) inherited from `System.Object`, and the following statements are permitted: > @@ -324,14 +324,6 @@ Every simple type has members. Each simple type that is an alias for a predefine > > *end note*. - - -The types `nint` and `nuint` are represented by the types `System.IntPtr` and `System.UIntPtr`, respectively, and are *not* aliases for these types. In this context being *represented by* means: - -- The only members directly accessible for `nint` and `nuint` are the required methods of `Object` ([§C.2](standard-library.md#c2-standard-library-types-defined-in-isoiec-23271)). Any other members of `System.IntPtr` and `System.UIntPtr` may be accessed via those types. -- Operations performed through `dynamic` binding on `System.IntPtr` and `System.UIntPtr` values do not have access to the `nint` and `nuint` operators. -- In all other respects `nint` and `nuint` behave as if they are aliases of `System.IntPtr` and `System.UIntPtr`. - ### 8.3.6 Integral types C# supports the following integral types, with the sizes and value ranges, as shown: diff --git a/standard/unsafe-code.md b/standard/unsafe-code.md index 866c5a4d0..8c850d03f 100644 --- a/standard/unsafe-code.md +++ b/standard/unsafe-code.md @@ -787,14 +787,20 @@ In an unsafe context, the `+` operator ([§12.13.5](expressions.md#12135-additio ```csharp T* operator +(T* x, int y); T* operator +(T* x, uint y); +T* operator +(T* x, nint y); +T* operator +(T* x, nuint y); T* operator +(T* x, long y); T* operator +(T* x, ulong y); T* operator +(int x, T* y); T* operator +(uint x, T* y); +T* operator +(nint x, T* y); +T* operator +(nuint x, T* y); T* operator +(long x, T* y); T* operator +(ulong x, T* y); T* operator –(T* x, int y); T* operator –(T* x, uint y); +T* operator -(T* x, nint y); +T* operator -(T* x, nuint y); T* operator –(T* x, long y); T* operator –(T* x, ulong y); long operator –(T* x, T* y); @@ -802,7 +808,7 @@ long operator –(T* x, T* y); There are no predefined operators for pointer addition or subtraction with native integer ([§8.3.6](types.md#836-integral-types)) offsets. Instead, `nint` and `nuint` values shall be promoted to `long` and `ulong`, respectively, with pointer arithmetic using the predefined operators for those types. -Given an expression `P` of a data pointer type `T*` and an expression `N` of type `int`, `uint`, `long`, or `ulong`, the expressions `P + N` and `N + P` compute the pointer value of type `T*` that results from adding `N * sizeof(T)` to the address given by `P`. Likewise, the expression `P – N` computes the pointer value of type `T*` that results from subtracting `N * sizeof(T)` from the address given by `P`. +Given an expression `P` of a data pointer type `T*` and an expression `N` of type `int`, `uint`, `nint`, `nuint`, `long`, or `ulong`, the expressions `P + N` and `N + P` compute the pointer value of type `T*` that results from adding `N * sizeof(T)` to the address given by `P`. Likewise, the expression `P – N` computes the pointer value of type `T*` that results from subtracting `N * sizeof(T)` from the address given by `P`. Given two expressions, `P` and `Q`, of a data pointer type `T*`, the expression `P – Q` computes the difference between the addresses given by `P` and `Q` and then divides that difference by `sizeof(T)`. The type of the result is always `long`. In effect, `P - Q` is computed as `((long)(P) - (long)(Q)) / sizeof(T)`.