Skip to content

Commit 787fe32

Browse files
committed
one final proofread
1 parent 8a010e8 commit 787fe32

File tree

1 file changed

+41
-62
lines changed

1 file changed

+41
-62
lines changed

docs/csharp/language-reference/compiler-messages/unsafe-code-errors.md

Lines changed: 41 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Resolve errors and warnings related to using unsafe code
3-
description: These compiler errors and warnings indicate errors when you work with `unsafe` code. Unsafe code requires special keywords before it's enabled. Unsafe code allows constructs that can introduce memory based errors. These warnings and errors explain common misues.
3+
description: These compiler errors and warnings indicate errors when you work with `unsafe` code. Unsafe code must be enabled with the `unsafe` keyword. Unsafe code allows constructs that can introduce memory based errors. These warnings and errors explain common misuses.
44
f1_keywords:
55
- "CS0193"
66
- "CS0196"
@@ -80,44 +80,44 @@ That's by design. The text closely matches the text of the compiler error / warn
8080
- [**CS0227**](#unsafe-context-restrictions): *Unsafe code may only appear if compiling with /unsafe*
8181
- [**CS0233**](#pointer-types-and-managed-types): *'identifier' does not have a predefined size, therefore sizeof can only be used in an unsafe context*
8282
- [**CS0242**](#pointer-operations-and-dereferencing): *The operation in question is undefined on void pointers*
83-
- [**CS0244**](#unsafe-context-restrictions): *Neither 'is' nor 'as' is valid on pointer types*
83+
- [**CS0244**](#unsafe-context-restrictions): *Neither '`is`' nor '`as`' is valid on pointer types*
8484
- [**CS0254**](#fixed-buffers): *The right hand side of a fixed statement assignment may not be a cast expression*
8585
- [**CS0459**](#fixed-buffers): *Cannot take the address of a read-only local variable*
8686
- [**CS0821**](#fixed-buffers): *Implicitly typed locals cannot be fixed*
8787
- [**CS1641**](#fixed-size-buffers): *A fixed size buffer field must have the array size specifier after the field name*
8888
- [**CS1642**](#fixed-size-buffers): *Fixed size buffer fields may only be members of structs.*
8989
- [**CS1656**](#fixed-buffers): *Cannot assign to 'variable' because it is a 'read-only variable type'*
90-
- [**CS1663**](#fixed-size-buffers): *Fixed size buffer type must be one of the following: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float or double*
90+
- [**CS1663**](#fixed-size-buffers): *Fixed size buffer type must be one of the following: `bool`, `byte`, `short`, `int`, `long`, `char`, `sbyte`, `ushort`, `uint`, `ulong`, `float` or `double`*
9191
- [**CS1665**](#fixed-size-buffers): *Fixed size buffers must have a length greater than zero*
9292
- [**CS1666**](#fixed-size-buffers): *You cannot use fixed size buffers contained in unfixed expressions. Try using the fixed statement.*
9393
- [**CS1708**](#fixed-size-buffers): *Fixed size buffers can only be accessed through locals or fields*
94-
- [**CS1716**](#fixed-size-buffers): *Do not use 'System.Runtime.CompilerServices.FixedBuffer' attribute. Use the 'fixed' field modifier instead.*
94+
- [**CS1716**](#fixed-size-buffers): *Do not use '`System.Runtime.CompilerServices.FixedBuffer`' attribute. Use the 'fixed' field modifier instead.*
9595
- [**CS1919**](#unsafe-context-restrictions): *Unsafe type 'type name' cannot be used in object creation.*
96-
- [**CS4004**](#unsafe-context-restrictions): *Cannot await in an unsafe context*
96+
- [**CS4004**](#unsafe-context-restrictions): *Cannot `await` in an unsafe context*
9797
- [**CS8812**](#function-pointers): *Cannot convert `&Method` group to non-function pointer type.*
9898
- [**CS9123**](#unsafe-context-restrictions): *The '`&`' operator should not be used on parameters or local variables in async methods.*
9999

100100
## Pointer operations and dereferencing
101101

102-
- **CS0193**: *The \* or -> operator must be applied to a data pointer*
102+
- **CS0193**: *The `*` or `->` operator must be applied to a data pointer*
103103
- **CS0196**: *A pointer must be indexed by only one value*
104104
- **CS0242**: *The operation in question is undefined on void pointers*
105105

106-
These errors occur when you attempt invalid operations on pointers. Pointers in C# have specific rules about dereferencing, indexing, and arithmetic operations. For more information, see [Pointer types](../unsafe-code.md#pointer-types) and [Function pointers](../unsafe-code.md#function-pointers).
106+
To use pointer operations correctly, follow the rules for dereferencing, indexing, and arithmetic operations. For more information, see [Pointer types](../unsafe-code.md#pointer-types) and [Function pointers](../unsafe-code.md#function-pointers).
107107

108-
- **CS0193** occurs when you use the `*` or `->` operator with a nonpointer type or with a function pointer. Function pointers cannot be dereferenced in C#, unlike in C/C++.
109-
- **CS0196** occurs when you attempt to index a pointer with multiple values. Pointers can only have a single index.
110-
- **CS0242** occurs when you attempt operations that are undefined on void pointers. For example, incrementing a void pointer is not allowed because the compiler doesn't know the size of the data being pointed to.
108+
- Apply the `*` or `->` operator only to data pointers (**CS0193**). Don't use these operators with nonpointer types or function pointers. Function pointers can't be dereferenced in C#, unlike in C/C++.
109+
- Index pointers with only one value (**CS0196**). Multidimensional indexing isn't supported on pointers.
110+
- Avoid operations that are undefined on void pointers (**CS0242**). For example, don't increment a void pointer because the compiler doesn't know the size of the data being pointed to.
111111

112112
## Pointer types and managed types
113113

114114
- **CS0208**: *Cannot take the address of, get the size of, or declare a pointer to a managed type ('type')*
115115
- **CS0233**: *'identifier' does not have a predefined size, therefore sizeof can only be used in an unsafe context*
116116

117-
These errors occur when you work with pointers to managed types or use the `sizeof` operator incorrectly. For more information, see [Unmanaged types](../builtin-types/unmanaged-types.md) and the [`sizeof` operator](../operators/sizeof.md).
117+
To work with pointers and the `sizeof` operator correctly, use unmanaged types and proper contexts. For more information, see [Unmanaged types](../builtin-types/unmanaged-types.md) and the [`sizeof` operator](../operators/sizeof.md).
118118

119-
- **CS0208** occurs when you attempt to take the address of, get the size of, or declare a pointer to a managed type. Even when used with the [`unsafe`](../keywords/unsafe.md) keyword, these operations are not allowed on managed types. A managed type is any reference type or any struct that contains a reference type as a field or property.
120-
- **CS0233** occurs when you use the [`sizeof`](../operators/sizeof.md) operator without an [`unsafe`](../keywords/unsafe.md) context on types whose size isn't a compile-time constant.
119+
- Use pointers only with unmanaged types (**CS0208**). Don't take the address of, get the size of, or declare pointers to managed types. Managed types include reference types and structs that contain reference type fields or properties.
120+
- Use the [`sizeof`](../operators/sizeof.md) operator within an [`unsafe`](../keywords/unsafe.md) context when working with types whose size isn't a compile-time constant (**CS0233**).
121121

122122
## Fixed buffers
123123

@@ -133,15 +133,17 @@ These errors occur when you work with pointers to managed types or use the `size
133133

134134
These errors occur when you use the [`fixed` statement](../statements/fixed.md) incorrectly. The `fixed` statement prevents the garbage collector from relocating a movable variable and declares a pointer to that variable. For more information, see [Unsafe Code and Pointers](../unsafe-code.md).
135135

136-
- **CS0209** occurs when the variable declared in a `fixed` statement isn't a pointer type.
137-
- **CS0210** occurs when you don't provide an initializer in a `fixed` statement declaration. You must declare and initialize the variable in the `fixed` statement.
138-
- **CS0211** occurs when you attempt to take the address of an expression that isn't valid for the address-of operator. You can take the address of fields, local variables, and pointer indirection, but not computed expressions like the sum of two variables.
139-
- **CS0212** occurs when you attempt to take the address of an unfixed expression outside of a `fixed` statement initializer. The address-of operator can only be used on unfixed expressions within the initializer of a `fixed` statement.
140-
- **CS0213** occurs when you attempt to use a `fixed` statement to take the address of an already-fixed expression. Local variables and parameters in an `unsafe` method are already fixed on the stack, so you don't need to (and cannot) fix them again.
141-
- **CS0254** occurs when the right side of a `fixed` statement assignment uses a cast expression. The `fixed` statement doesn't allow casts in its initializer.
142-
- **CS0459** occurs when you attempt to take the address of a read-only local variable. Variables in `foreach` loops, `using` statements, and `fixed` statements are read-only, and you cannot take their addresses.
143-
- **CS0821** occurs when you attempt to use an implicitly typed local variable (declared with `var`) in a `fixed` statement. The `fixed` statement requires an explicit type.
144-
- **CS1656** occurs when you attempt to assign to a variable in a read-only context, such as in a `foreach` loop, `using` statement, or `fixed` statement. Variables in these contexts are read-only and cannot be modified.
136+
To use the `fixed` statement correctly:
137+
138+
- Declare the variable as a pointer type (**CS0209**).
139+
- Provide an initializer in the `fixed` statement declaration (**CS0210**).
140+
- Take the address only of valid expressions: fields, local variables, and pointer indirection (**CS0211**). Don't take the address of computed expressions like the sum of two variables.
141+
- Use the address-of operator on unfixed expressions only within the `fixed` statement initializer (**CS0212**).
142+
- Don't use a `fixed` statement on already-fixed expressions (**CS0213**). Local variables and parameters in an `unsafe` method are already fixed on the stack.
143+
- Don't use cast expressions on the right side of a `fixed` statement assignment (**CS0254**).
144+
- Don't take the address of read-only local variables (**CS0459**). Variables in `foreach` loops, `using` statements, and `fixed` statements are read-only.
145+
- Use explicit types instead of `var` in `fixed` statements (**CS0821**).
146+
- Don't assign to variables in read-only contexts like `foreach` loops, `using` statements, or `fixed` statements (**CS1656**).
145147

146148
## Unsafe context restrictions
147149

@@ -154,12 +156,14 @@ These errors occur when you use the [`fixed` statement](../statements/fixed.md)
154156

155157
These errors occur when you use unsafe code constructs without proper unsafe context or when you attempt operations that aren't allowed in unsafe code. For more information, see [Unsafe Code and Pointers](../unsafe-code.md) and the [`unsafe` keyword](../keywords/unsafe.md).
156158

157-
- **CS0214** occurs when you use pointers or fixed-size buffers outside an `unsafe` context. Mark the method, type, or code block with the `unsafe` keyword.
158-
- **CS0227** occurs when source code contains the `unsafe` keyword but the [**AllowUnsafeBlocks**](../compiler-options/language.md#allowunsafeblocks) compiler option isn't enabled. Enable unsafe code in your project settings.
159-
- **CS0244** occurs when you use the [`is`](../operators/type-testing-and-cast.md#the-is-operator) or [`as`](../operators/type-testing-and-cast.md#the-as-operator) operators with pointer types. These type-testing operators aren't valid for pointers.
160-
- **CS1919** occurs when you use the `new` operator to create an instance of a pointer type. The `new` operator creates objects only on the managed heap. To create objects in unmanaged memory, use interop to call native methods that return pointers.
161-
- **CS4004** occurs when you use the `await` keyword in an `unsafe` context. Separate unsafe code from awaitable code by creating separate methods.
162-
- **CS9123** is a warning that occurs when you use the address-of operator (`&`) on parameters or local variables in async methods. This can lead to issues because the variable may not exist when the async operation completes.
159+
To use unsafe code correctly:
160+
161+
- Mark methods, types, or code blocks that use pointers or fixed-size buffers with the `unsafe` keyword (**CS0214**).
162+
- Enable the [**AllowUnsafeBlocks**](../compiler-options/language.md#allowunsafeblocks) compiler option in your project settings when using the `unsafe` keyword (**CS0227**).
163+
- Don't use the [`is`](../operators/type-testing-and-cast.md#the-is-operator) or [`as`](../operators/type-testing-and-cast.md#the-as-operator) operators with pointer types (**CS0244**). These type-testing operators aren't valid for pointers.
164+
- Don't use the `new` operator to create pointer type instances (**CS1919**). To create objects in unmanaged memory, use interop to call native methods that return pointers.
165+
- Keep unsafe code separate from async code (**CS4004**). Create separate methods for unsafe operations and call them from async methods.
166+
- Don't use the address-of operator (`&`) on parameters or local variables in async methods (**CS9123**). The variable may not exist when the async operation completes.
163167

164168
## Fixed-size buffers
165169

@@ -173,42 +177,17 @@ These errors occur when you use unsafe code constructs without proper unsafe con
173177

174178
These errors occur when you work with fixed-size buffers. Fixed-size buffers are arrays embedded directly in structs and are primarily used for interop scenarios. For more information, see [Fixed-size buffers](../../language-reference/unsafe-code.md#fixed-size-buffers).
175179

176-
- **CS1641** occurs when a fixed-size buffer declaration is missing the array size specifier. Unlike regular arrays, fixed-size buffers require a constant size specified at declaration.
177-
- **CS1642** occurs when you declare a fixed-size buffer field in a `class`. Fixed-size buffers can only be members of structs. Change the `class` to a `struct` or use a regular array instead.
178-
- **CS1663** occurs when the element type of a fixed-size buffer isn't one of the supported types: `bool`, `byte`, `short`, `int`, `long`, `char`, `sbyte`, `ushort`, `uint`, `ulong`, `float`, or `double`.
179-
- **CS1665** occurs when a fixed-size buffer is declared with a length of zero or a negative number. Fixed-size buffers must have a positive length.
180-
- **CS1666** occurs when you attempt to use a fixed-size buffer in an unfixed expression. You must use a `fixed` statement to pin the containing struct before accessing the buffer.
181-
- **CS1708** occurs when you attempt to access a fixed-size buffer through an invalid expression. Fixed-size buffers can only be accessed through locals or fields.
182-
- **CS1716** occurs when you use the `System.Runtime.CompilerServices.FixedBuffer` attribute directly. Use the `fixed` field modifier instead.
180+
To declare and use fixed-size buffers correctly:
181+
182+
- Specify the array size after the field name using a positive integer constant (**CS1641**, **CS1665**).
183+
- Declare fixed-size buffers only in structs, not in classes (**CS1642**). Use a regular array if you need the field in a class.
184+
- Use one of the supported element types: `bool`, `byte`, `short`, `int`, `long`, `char`, `sbyte`, `ushort`, `uint`, `ulong`, `float`, or `double` (**CS1663**).
185+
- Use a `fixed` statement to pin the containing struct before accessing the buffer (**CS1666**).
186+
- Access fixed-size buffers only through locals or fields, not through intermediate expressions (**CS1708**).
187+
- Use the `fixed` field modifier instead of the `System.Runtime.CompilerServices.FixedBuffer` attribute (**CS1716**).
183188

184189
## Function pointers
185190

186191
- **CS8812**: *Cannot convert `&Method` group to non-function pointer type*
187192

188-
This error occurs when you attempt to convert a method group address to a non-function pointer type. The address of a method (for example, `&Method`) obtained using the [address-of operator `&`](../operators/pointer-related-operators.md#address-of-operator-) doesn't have an implicit type and cannot be assigned to a non-function pointer variable without an explicit cast. For more information, see [Function pointers](../unsafe-code.md#function-pointers).
189-
190-
The following sample generates CS8812:
191-
192-
```csharp
193-
// CS8812.cs (6,22)
194-
195-
unsafe class C
196-
{
197-
static void Method()
198-
{
199-
void* ptr1 = &Method;
200-
}
201-
}
202-
```
203-
204-
To correct this error, explicitly convert the expression to the required function pointer type:
205-
206-
```csharp
207-
unsafe class C
208-
{
209-
static void Method()
210-
{
211-
void* ptr1 = (delegate*<void>)&Method;
212-
}
213-
}
214-
```
193+
To obtain a function pointer, use the address-of operator with an explicit function pointer type cast. Don't use the [address-of operator `&`](../operators/pointer-related-operators.md#address-of-operator-) to assign method groups to `void*` or other non-function pointer types. For more information, see [Function pointers](../unsafe-code.md#function-pointers).

0 commit comments

Comments
 (0)