diff --git a/standard/conversions.md b/standard/conversions.md index bde36b203..dbb3601df 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 53172597d..5839b13db 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); @@ -298,7 +300,6 @@ When overload resolution rules ([§12.6.4](expressions.md#1264-overload-resoluti > *Example*: For the operation `b * s`, where `b` is a `byte` and `s` is a `short`, overload resolution selects `operator *(int, int)` as the best operator. Thus, the effect is that `b` and `s` are converted to `int`, and the type of the result is `int`. Likewise, for the operation `i * d`, where `i` is an `int` and `d` is a `double`, `overload` resolution selects `operator *(double, double)` as the best operator. *end example* - **End of informative text.** #### 12.4.7.2 Unary numeric promotions diff --git a/standard/types.md b/standard/types.md index f0dc27ec7..40151cdb0 100644 --- a/standard/types.md +++ b/standard/types.md @@ -275,7 +275,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** ----------- | ------------------ @@ -285,8 +285,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` @@ -295,7 +295,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: > diff --git a/standard/unsafe-code.md b/standard/unsafe-code.md index 73f1d863f..729136821 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)`.