Skip to content

Remove references to pointers within the standard where appropriate. #678

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 1, 2023
Merged
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
7 changes: 2 additions & 5 deletions standard/classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ A *primary_expression* ([§11.7](expressions.md#117-primary-expressions)) is per

In any other context, it is a compile-time error to reference a static class.

> *Note*: For example, it is an error for a static class to be used as a base class, a constituent type ([§14.3.7](classes.md#1437-constituent-types)) of a member, a generic type argument, or a type parameter constraint. Likewise, a static class cannot be used in an array type, a pointer type, a new expression, a cast expression, an is expression, an as expression, a `sizeof` expression, or a default value expression. *end note*
> *Note*: For example, it is an error for a static class to be used as a base class, a constituent type ([§14.3.7](classes.md#1437-constituent-types)) of a member, a generic type argument, or a type parameter constraint. Likewise, a static class cannot be used in an array type, a new expression, a cast expression, an is expression, an as expression, a `sizeof` expression, or a default value expression. *end note*

### 14.2.3 Type parameters

Expand Down Expand Up @@ -442,8 +442,6 @@ The value type constraint specifies that a type argument used for the type param

> *Note*: The `System.Nullable<T>` type specifies the non-nullable value type constraint for `T`. Thus, recursively constructed types of the forms `T??` and `Nullable<Nullable<T>>` are prohibited. *end note*

Pointer types are never allowed to be type arguments and are not considered to satisfy either the reference type or value type constraints.

If a constraint is a class type, an interface type, or a type parameter, that type specifies a minimal “base type” that every type argument used for that type parameter shall support. Whenever a constructed type or generic method is used, the type argument is checked against the constraints on the type parameter at compile-time. The type argument supplied shall satisfy the conditions described in [§8.4.5](types.md#845-satisfying-constraints).

A *class_type* constraint shall satisfy the following rules:
Expand Down Expand Up @@ -567,7 +565,6 @@ The ***dynamic erasure*** of a type `C` is type `Cₓ` constructed as follows:
- If `C` is a nested type `Outer.Inner` then `Cₓ` is a nested type `Outerₓ.Innerₓ`.
- If `C` `Cₓ`is a constructed type `G<A¹, ..., Aⁿ>` with type arguments `A¹, ..., Aⁿ` then `Cₓ` is the constructed type `G<A¹ₓ, ..., Aⁿₓ>`.
- If `C` is an array type `E[]` then `Cₓ` is the array type `Eₓ[]`.
- If `C` is a pointer type `E*` then `Cₓ` is the pointer type `Eₓ*`.
- If `C` is dynamic then `Cₓ` is `object`.
- Otherwise, `Cₓ` is `C`.

Expand Down Expand Up @@ -2961,7 +2958,7 @@ class Customer

### 14.6.10 Extension methods

When the first parameter of a method includes the `this` modifier, that method is said to be an ***extension method***. Extension methods shall only be declared in non-generic, non-nested static classes. The first parameter of an extension method may have no modifiers other than `this`, and the parameter type may not be a pointer type.
When the first parameter of a method includes the `this` modifier, that method is said to be an ***extension method***. Extension methods shall only be declared in non-generic, non-nested static classes. The first parameter of an extension method may have no modifiers other than `this`.

> *Example*: The following is an example of a static class that declares two extension methods:
>
Expand Down
2 changes: 1 addition & 1 deletion standard/expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2580,7 +2580,7 @@ class __Anonymous1
}
```

where each «Tx» is the type of the corresponding expression «ex». The expression used in a *member_declarator* shall have a type. Thus, it is a compile-time error for an expression in a *member_declarator* to be `null` or an anonymous function. It is also a compile-time error for the expression to have a pointer type ([§22.3](unsafe-code.md#223-pointer-types)).
where each «Tx» is the type of the corresponding expression «ex». The expression used in a *member_declarator* shall have a type. Thus, it is a compile-time error for an expression in a *member_declarator* to be `null` or an anonymous function.

The names of an anonymous type and of the parameter to its `Equals` method are automatically generated by the compiler and cannot be referenced in program text.

Expand Down
3 changes: 1 addition & 2 deletions standard/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ type_argument
;
```

A *type_argument* shall not be a pointer type ([§22](unsafe-code.md#22-unsafe-code)). Each type argument shall satisfy any constraints on the corresponding type parameter ([§14.2.5](classes.md#1425-type-parameter-constraints)).
Each type argument shall satisfy any constraints on the corresponding type parameter ([§14.2.5](classes.md#1425-type-parameter-constraints)).

### 8.4.3 Open and closed types

Expand Down Expand Up @@ -650,4 +650,3 @@ An *unmanaged_type* is any type that isn’t a *reference_type*, a *type_paramet
- `sbyte`, `byte`, `short`, `ushort`, `int`, `uint`, `long`, `ulong`, `char`, `float`, `double`, `decimal`, or `bool`.
- Any *enum_type*.
- Any user-defined *struct_type* that is not a constructed type and contains fields of *unmanaged_type*s only.
- In unsafe code ([§22.2](unsafe-code.md#222-unsafe-contexts)), any *pointer_type* ([§22.3](unsafe-code.md#223-pointer-types)).
10 changes: 9 additions & 1 deletion standard/unsafe-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ The type specified before the `*` in a pointer type is called the ***referent ty

A *pointer_type* may only be used in an *array_type* in an unsafe context ([§22.2](unsafe-code.md#222-unsafe-contexts)). A *non_array_type* is any type that is not itself an *array_type*.

Unlike references (values of reference types), pointers are not tracked by the garbage collector—the garbage collector has no knowledge of pointers and the data to which they point. For this reason a pointer is not permitted to point to a reference or to a struct that contains references, and the referent type of a pointer shall be an *unmanaged_type*.
Unlike references (values of reference types), pointers are not tracked by the garbage collector—the garbage collector has no knowledge of pointers and the data to which they point. For this reason a pointer is not permitted to point to a reference or to a struct that contains references, and the referent type of a pointer shall be an *unmanaged_type*. Pointer types themselves are unmanaged types, so a pointer type may be used as the referent type for another pointer type.

The intuitive rule for mixing of pointers and references is that referents of references (objects) are permitted to contain pointers, but referents of pointers are not permitted to contain references.

Expand Down Expand Up @@ -170,8 +170,16 @@ A *pointer_type* cannot be used as a type argument ([§8.4](types.md#84-construc

A *pointer_type* cannot be used as a type of a subexpression of a dynamically bound operation ([§11.3.3](expressions.md#1133-dynamic-binding)).

A *pointer_type* cannot be used as the type of the first parameter in an extension method ([§14.6.10](classes.md#14610-extension-methods)).

A *pointer_type* may be used as the type of a volatile field ([§14.5.4](classes.md#1454-volatile-fields)).

The *dynamic erasure* of a type `E*` is the pointer type with referent type of the dynamic erasure of `E`.

An expression with a pointer type cannot be used to provide the value in a *member_declarator* within an *anonymous_object_creation_expression* ([§11.7.15.7](expressions.md#117157-anonymous-object-creation-expressions)).

The default value ([§9.3](variables.md#93-default-values)) for any pointer type is `null`.

> *Note*: Although pointers can be passed as `ref` or `out` parameters, doing so can cause undefined behavior, since the pointer might well be set to point to a local variable that no longer exists when the called method returns, or the fixed object to which it used to point, is no longer fixed. For example:
>
> <!-- UndefinedExample: {template:"standalone-console", name:"PointerTypes1", replaceEllipsis:true, expectedOutput:["*px1 = 10","*px2 = 20"], expectedWarnings:["x","x"]} -->
Expand Down
1 change: 0 additions & 1 deletion standard/variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,6 @@ The default value of a variable depends on the type of the variable and is deter

- For a variable of a *value_type*, the default value is the same as the value computed by the *value_type*’s default constructor ([§8.3.3](types.md#833-default-constructors)).
- For a variable of a *reference_type*, the default value is `null`.
- In an unsafe context, for a variable of a *pointer_type*, the default value is `null`.

> *Note*: Initialization to default values is typically done by having the memory manager or garbage collector initialize memory to all-bits-zero before it is allocated for use. For this reason, it is convenient to use all-bits-zero to represent the null reference. *end note*

Expand Down