ECMA-334 C# Language Specification25.2: Pointer types |
In an unsafe context, a type (11) may be a pointer-type
as well as a value-type
or a reference-type
.
value-type
reference-type
pointer-type
A pointer-type
is written as an unmanaged-type
or the keyword void , followed by a * token: unmanaged-type
*
*
type
The type specified before the * in a pointer type is called the referent type of the pointer type. It represents the type of the variable to which a value of the pointer type points.
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 must be an unmanaged-type
.
An unmanaged-type
is any type that isn't a reference-type
and doesn't contain reference-type
fields at any level of nesting. In other words, an unmanaged-type
is one of the following:
enum-type
. pointer-type
. struct-type
that contains fields of unmanaged-type
s only. 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.
For a given implementation, all pointer types must have the same size and representation.
end note]
int* pi, pj; // NOT as int *pi, *pj;
The value of a pointer having type T* represents the address of a variable of type T. The pointer indirection operator * (25.5.1) may be used to access this variable. For example, given a variable P of type int*, the expression *P denotes the int variable found at the address contained in P.
Like an object reference, a pointer may be null. Applying the indirection operator to a null pointer results in implementation-defined behavior. A pointer with value null is represented by all-bits-zero.
The void* type represents a pointer to an unknown type. Because the referent type is unknown, the indirection operator cannot be applied to a pointer of type void*, nor can any arithmetic be performed on such a pointer. However, a pointer of type void* can be cast to any other pointer type (and vice versa).
Pointer types are a separate category of types. Unlike reference types and value types, pointer types do not inherit from object and no conversions exist between pointer types and object. In particular, boxing and unboxing (11.3) are not supported for pointers. However, conversions are permitted between different pointer types and between pointer types and the integral types. This is described in 25.4.
A pointer-type
may be used as the type of a volatile field (17.4.3).
end note]
using System;
class Test
{
static int value = 20;
unsafe static void F(out int* pi1, ref int* pi2) {
int i = 10;
pi1 = &i;
fixed (int* pj = &value) {
// ...
pi2 = pj;
}
}
static void Main() {
int i = 10;
unsafe {
int* px1;
int* px2 = &i;
F(out px1, ref px2);
Console.WriteLine("*px1 = {0}, *px2 = {1}",
*px1, *px2); // undefined behavior
}
}
}
A method can return a value of some type, and that type can be a pointer.
end example]
unsafe static int* Find(int* pi, int size, int value) {
for (int i = 0; i < size; ++i) {
if (*pi == value) {
return pi;
}
++pi;
}
return null;
}
In an unsafe context, several constructs are available for operating on pointers: