Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions standard/conversions.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,6 @@

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
Expand Down Expand Up @@ -854,7 +852,7 @@
>
> var amt6 = 66036; // var types amt6 as int
> var dose6 = (Dose)amt6; // amt3 is int, int to ushort conversion added
> // warning as information loss may occur

Check warning on line 855 in standard/conversions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/conversions.md#L855

MDC032::Line length 82 > maximum 81
> Console.WriteLine(dose6); // outputs 500mg, not 66036mg, due to information loss
>
> // Using a constructor instead of user-defined conversion:
Expand Down
41 changes: 39 additions & 2 deletions standard/expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,8 @@
```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);
Expand All @@ -298,8 +300,6 @@

> *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*

There are no predefined operators for dealing with native integer ([§8.3.6](types.md#836-integral-types)). Instead, `nint` and `nuint` values shall be promoted to `long` and `ulong`, respectively, and the resulting corresponding predefined operators used instead.

**End of informative text.**

#### 12.4.7.2 Unary numeric promotions
Expand Down Expand Up @@ -2292,8 +2292,8 @@
A *null_conditional_invocation_expression* is syntactically either a *null_conditional_member_access* ([§12.8.8](expressions.md#1288-null-conditional-member-access)) or *null_conditional_element_access* ([§12.8.13](expressions.md#12813-null-conditional-element-access)) where the final *dependent_access* is an invocation expression ([§12.8.10](expressions.md#12810-invocation-expressions)).

A *null_conditional_invocation_expression* occurs within the context of a *statement_expression* ([§13.7](statements.md#137-expression-statements)), *anonymous_function_body* ([§12.22.1](expressions.md#12221-general)), or *method_body* ([§15.6.1](classes.md#1561-general)).

Check warning on line 2295 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/expressions.md#L2295

MDC032::Line length 84 > maximum 81
Unlike the syntactically equivalent *null_conditional_member_access* or *null_conditional_element_access*, a *null_conditional_invocation_expression* may be classified as nothing.

Check warning on line 2296 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/expressions.md#L2296

MDC032::Line length 85 > maximum 81

```ANTLR
null_conditional_invocation_expression
Expand Down Expand Up @@ -2373,7 +2373,7 @@
- The *primary_expression* has compile-time type `dynamic`.
- At least one expression of the *argument_list* has compile-time type `dynamic`.

In this case the compile-time type of the *element_access* depends on the compile-time type of its *primary_expression*: if it has an array type then the compile-time type is the element type of that array type; otherwise the compile-time type is `dynamic` and the *element_access* is classified as a value of type `dynamic`. The rules below to determine the meaning of the *element_access* are then applied at run-time, using the run-time type instead of the compile-time type of those of the *primary_expression* and *argument_list* expressions which have the compile-time type `dynamic`. If the *primary_expression* does not have compile-time type `dynamic`, then the element access undergoes a limited compile-time check as described in [§12.6.5](expressions.md#1265-compile-time-checking-of-dynamic-member-invocation).

Check warning on line 2376 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/expressions.md#L2376

MDC032::Line length 82 > maximum 81

> *Example*:
>
Expand Down Expand Up @@ -3518,7 +3518,7 @@
- one of the following value types: `sbyte`, `byte`, `short`, `ushort`, `int`, `uint`, `nint`, `nuint`, `long`, `ulong`, `char`, `float`, `double`, `decimal`, `bool`; or
- any enumeration type.

### 12.8.22 Stack allocation

Check warning on line 3521 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/expressions.md#L3521

MDC032::Line length 86 > maximum 81

A stack allocation expression allocates a block of memory from the execution stack. The ***execution stack*** is an area of memory where local variables are stored. The execution stack is not part of the managed heap. The memory used for local variable storage is automatically recovered when the current function returns.

Expand Down Expand Up @@ -3733,6 +3733,8 @@
```csharp
int operator +(int x);
uint operator +(uint x);
nint operator +(nint x);
nuint operator +(nuint x);
long operator +(long x);
ulong operator +(ulong x);
float operator +(float x);
Expand All @@ -3752,6 +3754,7 @@

```csharp
int operator –(int x);
nint operator –(nint x);
long operator –(long x);
```

Expand Down Expand Up @@ -3801,6 +3804,8 @@
```csharp
int operator ~(int x);
uint operator ~(uint x);
nint operator ~(nint x);
nuint operator ~(nuint x);
long operator ~(long x);
ulong operator ~(ulong x);
```
Expand Down Expand Up @@ -3986,8 +3991,8 @@
All non-positional properties being changed shall have both set and init accessors.

This expression is evaluated as follows:

Check warning on line 3994 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/expressions.md#L3994

MDC032::Line length 84 > maximum 81
- For a record class type, the receiver's clone method ([§15.16.3](classes.md#15163-copy-and-clone-members)) is invoked, and its result is converted to the receiver’s type.

Check warning on line 3995 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/expressions.md#L3995

MDC032::Line length 85 > maximum 81
- Each `member_initializer` is processed the same way as an assignment to
a field or property access of the result of the conversion. Assignments are processed in lexical order. If *member_initializer_list* is omitted, no members are changed.

Expand Down Expand Up @@ -4146,6 +4151,8 @@
```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);
```
Expand Down Expand Up @@ -4193,6 +4200,8 @@
```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);
```
Expand Down Expand Up @@ -4244,6 +4253,8 @@
```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);
```
Expand Down Expand Up @@ -4294,6 +4305,8 @@
```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);
```
Expand Down Expand Up @@ -4396,6 +4409,8 @@
```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
```
Expand Down Expand Up @@ -4521,6 +4536,8 @@
```csharp
int operator <<(int x, int count);
uint operator <<(uint x, int count);
nint operator <<(nint x, int count);
nuint operator <<(nuint x, int count);
long operator <<(long x, int count);
ulong operator <<(ulong x, int count);
```
Expand All @@ -4533,6 +4550,8 @@
```csharp
int operator >>(int x, int count);
uint operator >>(uint x, int count);
nint operator >>(nint x, int count);
nuint operator >>(nuint x, int count);
long operator >>(long x, int count);
ulong operator >>(ulong x, int count);
```
Expand Down Expand Up @@ -4619,31 +4638,43 @@
```csharp
bool operator ==(int x, int y);
bool operator ==(uint x, uint y);
bool operator ==(nint x, nint y);
bool operator ==(nuint x, nuint y);
bool operator ==(long x, long y);
bool operator ==(ulong x, ulong y);

bool operator !=(int x, int y);
bool operator !=(uint x, uint y);
bool operator !=(nint x, nint y);
bool operator !=(nuint x, nuint y);
bool operator !=(long x, long y);
bool operator !=(ulong x, ulong y);

bool operator <(int x, int y);
bool operator <(uint x, uint y);
bool operator <(nint x, nint y);
bool operator <(nuint x, nuint y);
bool operator <(long x, long y);
bool operator <(ulong x, ulong y);

bool operator >(int x, int y);
bool operator >(uint x, uint y);
bool operator >(nint x, nint y);
bool operator >(nuint x, nuint y);
bool operator >(long x, long y);
bool operator >(ulong x, ulong y);

bool operator <=(int x, int y);
bool operator <=(uint x, uint y);
bool operator <=(nint x, nint y);
bool operator <=(nuint x, nuint y);
bool operator <=(long x, long y);
bool operator <=(ulong x, ulong y);

bool operator >=(int x, int y);
bool operator >=(uint x, uint y);
bool operator >=(nint x, nint y);
bool operator >=(nuint x, nuint y);
bool operator >=(long x, long y);
bool operator >=(ulong x, ulong y);
```
Expand Down Expand Up @@ -5098,16 +5129,22 @@
```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);

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);

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);
```
Expand Down Expand Up @@ -5434,7 +5471,7 @@
An ***anonymous function*** is an expression that represents an “in-line” method definition. An anonymous function does not have a value or type in and of itself, but is convertible to a compatible delegate or expression-tree type. The evaluation of an anonymous-function conversion depends on the target type of the conversion: If it is a delegate type, the conversion evaluates to a delegate value referencing the method that the anonymous function defines. If it is an expression-tree type, the conversion evaluates to an expression tree that represents the structure of the method as an object structure.

> *Note*: For historical reasons, there are two syntactic flavors of anonymous functions, namely *lambda_expression* and *anonymous_method_expression*. For almost all purposes, *lambda_expression* is more concise and expressive than *anonymous_method_expression*s, which remain in the language for backwards compatibility. *end note*

Check warning on line 5474 in standard/expressions.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/expressions.md#L5474

MDC032::Line length 90 > maximum 81
```ANTLR
lambda_expression
: attributes? anonymous_function_modifier?
Expand Down
8 changes: 4 additions & 4 deletions standard/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@

### 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**
----------- | ------------------
Expand All @@ -283,8 +283,8 @@
`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`
Expand All @@ -293,7 +293,7 @@
`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 the members declared in `System.Int32` and the members inherited from `System.Object`, and the following statements are permitted:
>
Expand Down Expand Up @@ -1077,8 +1077,8 @@
> {
> var t = new Test();
> if (t.DisappearingProperty != null)
> {

Check warning on line 1080 in standard/types.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/types.md#L1080

MDC032::Line length 82 > maximum 81
> int len = t.DisappearingProperty.Length; // No warning. A compiler can

Check warning on line 1081 in standard/types.md

View workflow job for this annotation

GitHub Actions / Markdown to Word Converter

standard/types.md#L1081

MDC032::Line length 83 > maximum 81
> // assume property is stateful
> }
> }
Expand Down
8 changes: 7 additions & 1 deletion standard/unsafe-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -787,22 +787,28 @@ 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);
```

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)`.

Expand Down
Loading