-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
216 additions
and
1 deletion.
There are no files selected for viewing
2 changes: 1 addition & 1 deletion
2
...ur first source generator for `csharp`.md → ...docs/Start your first source generator.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
docs/document/Unsafe CSharp/docs/Fundamentals/1. Releasing unsafe power.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Releasing unsafe power | ||
|
||
```xml | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> // [!code ++] | ||
</PropertyGroup> | ||
|
||
</Project> | ||
``` |
49 changes: 49 additions & 0 deletions
49
docs/document/Unsafe CSharp/docs/Fundamentals/2. Pointer operators.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# Pointer operators | ||
|
||
For all value and reference types, there's a pointer version of it(`T*`), **the pointer instance stores the address of the variable**. | ||
|
||
|operator|name|usage| | ||
|---|---|---| | ||
|`&`|address-of operator|returns a pointer to the address of a variable| | ||
|`*`|dereference operator|returns the variable at the address of a pointer, in other words, returns a pointer| | ||
|`->`|pointer-to-member operator|syntactic sugar in which `x->y` is equivalent to `(*x).y`| | ||
|`++`|pointer addition operator|adds `sizeof(T)` to the address contained in the variable| | ||
|`--`|pointer subtraction operator|subtracts `sizeof(T)` to the address contained in the variable| | ||
|`[]`|pointer element accessor|retrieve value of address with an offset, in which `p[i]` is equivalent to `*(p + i)`| | ||
|
||
## Pointer Increment and Decrement | ||
|
||
If a pointer increment or decrement operation overflows the domain of the pointer type, the result is implementation-defined, but no exceptions are produced. | ||
|
||
```cs | ||
T* operator ++(T* x); | ||
T* operator --(T* x); | ||
``` | ||
|
||
## Pointer Arithmetic | ||
|
||
```cs | ||
T* operator +(T* x, int y); | ||
T* operator +(T* x, uint 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 +(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, long y); | ||
T* operator –(T* x, ulong y); | ||
long operator –(T* x, T* y); | ||
``` | ||
|
||
## Pointer comparison | ||
|
||
See [Void Pointer](./5.%20Void%20Pointer.md#Built-in%20operator) | ||
|
||
## Operator priority | ||
|
||
- `++` or `--` > `*`, `*p++` is equivalent to `*(p++)`. | ||
|
||
## `sizeof` Operator |
66 changes: 66 additions & 0 deletions
66
docs/document/Unsafe CSharp/docs/Fundamentals/3. Fixed statement.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# Fixed statement | ||
|
||
## Motivation | ||
|
||
GC may move a managed object around during runtime, so pointing to its address is not reliable since the address possibly changes all the time. So `fixed` is to tell the GC not moving the object around. | ||
|
||
```cs | ||
Person person = new(); | ||
unsafe | ||
{ | ||
// get address of a field and assign it to a new pointer | ||
fixed (int* ptr = &person.Age) | ||
{ | ||
// dereferencing, in which returns the variable and assign new value | ||
*ptr = 123; | ||
} | ||
Console.WriteLine(person.Age); | ||
} | ||
|
||
class Person { public int Age; } | ||
``` | ||
|
||
## Managed and Unmanaged | ||
|
||
- All enums are unmanaged | ||
- All pointers are unmanaged | ||
- All primitive types are unmanaged. | ||
- User defined struct containing no managed field are unmanaged | ||
|
||
## When to use `fixed`? | ||
|
||
```cs | ||
class K { public int k; } | ||
struct C | ||
{ | ||
public int instanceMember; | ||
public readonly static int shared; | ||
public const int con = 0; | ||
unsafe void M(int j, K k) | ||
{ | ||
fixed (int* p = &j) { } // CS0213 | ||
fixed (int* p = &k.k) { } | ||
int local = 0; | ||
fixed (int* p = &local) { } // CS0213 | ||
int[] localArray = []; | ||
fixed (int* p = localArray) fixed (int* pp = p) { } // CS8385 | ||
string localString = "abc"; | ||
fixed (char* p = localString) fixed (char* pp = p) { } // CS8385 | ||
K kk = new(); | ||
fixed (int* p = &kk.k) { } | ||
fixed (int* p = &this.instanceMember) { } | ||
fixed (int* p = &C.shared) { } | ||
fixed (int* p = &C.con) { } // CS0211 | ||
} | ||
} | ||
``` | ||
|
||
1. `j` lives inside the method only, and it's unmanaged so compiler yells. | ||
2. `k` as a reference type and managed object, can be fixed. | ||
3. local unmanaged can't be fixed | ||
4. local array is managed but `p` is already fixed in previous statement. | ||
5. same as 5. | ||
6. local managed can be fixed | ||
7. | ||
8. static fields are kept alive until the program ends then GC collects, so it's managed. | ||
9. constants are simply values, not variable or field, there's no address for them. |
31 changes: 31 additions & 0 deletions
31
docs/document/Unsafe CSharp/docs/Fundamentals/4. Fixed-Size buffer.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Fixed-Size buffer | ||
|
||
## Motivation | ||
|
||
Fixed-size buffers are used to declare “C-style” in-line arrays as members of structs, and are primarily useful for interfacing with unmanaged APIs. | ||
|
||
## Constraint | ||
|
||
- Length of fixed-size buffer may only be constant. | ||
- Fixed-size buffer may only be **declared and accessed** in unsafe context. | ||
|
||
```cs | ||
C c = new(); | ||
_ = c.Buffer[0]; // CS0214 | ||
struct C | ||
{ | ||
public unsafe fixed byte Buffer[30]; | ||
public unsafe void M() | ||
{ | ||
C c = new(); | ||
_ = c.Buffer[0]; | ||
} | ||
} | ||
``` | ||
|
||
- **May not be static.** But instance of its containing type can be static. | ||
- Element type must be one of the following: `bool`, `byte`, `short`, `int`, `long`, `char`, `sbyte`, `ushort`, `uint`, `ulong`, `float` or `double`. | ||
|
||
```cs | ||
|
||
``` |
19 changes: 19 additions & 0 deletions
19
docs/document/Unsafe CSharp/docs/Fundamentals/5. Void Pointer.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Void Pointer | ||
|
||
`void*` is the loosely typed version of any pointer(like `object` for non pointer types), the underlying type of the original pointer is mopped, so | ||
|
||
- Cannot be deferenced. | ||
- Arithmetic can not be performed. | ||
|
||
## Pointer comparison | ||
|
||
Because an implicit conversion exists from any pointer type to the void* type, operands of any pointer type can be compared using these operators. The comparison operators compare the addresses given by the two operands as if they were unsigned integers. | ||
|
||
```cs | ||
bool operator ==(void* x, void* y); | ||
bool operator !=(void* x, void* y); | ||
bool operator <(void* x, void* y); | ||
bool operator >(void* x, void* y); | ||
bool operator <=(void* x, void* y); | ||
bool operator >=(void* x, void* y); | ||
``` |
16 changes: 16 additions & 0 deletions
16
docs/document/Unsafe CSharp/docs/Fundamentals/6. Pointer Conversion.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# Pointer Conversion | ||
|
||
## What does conversion do? | ||
|
||
Conversions between two pointer types never change the actual pointer value. In other words, a conversion from one pointer type to another has no effect on the underlying address given by the pointer. | ||
|
||
## Implicit Conversion | ||
|
||
- Any pointer type to `void*`. | ||
- `null` to any pointer type. | ||
|
||
## Explicit Conversion | ||
|
||
- `sbyte`, `byte`, `short`, `ushort`, `int`, `uint`, `long`, or `ulong` to any pointer type. | ||
- any pointer type to any other pointer type. | ||
- any pointer type to `sbyte`, `byte`, `short`, `ushort`, `int`, `uint`, `long`, or `ulong`. |
13 changes: 13 additions & 0 deletions
13
docs/document/Unsafe CSharp/docs/Fundamentals/7. Stack Allocation.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Stack Allocation | ||
|
||
## `stackalloc` Operator | ||
|
||
- The natural type `stackalloc` returns is the pointer of target element type(`TUnmanaged*`). | ||
- Element type must be unmanaged type. | ||
- Similar to `new` operator, compiler can infer the target type; | ||
|
||
```cs | ||
_ = stackalloc int[] { 1, 2, 3 }; | ||
_ = stackalloc[] { 1d, 2d, 3f }; | ||
_ = stackalloc byte[10]; | ||
``` |
6 changes: 6 additions & 0 deletions
6
docs/document/Unsafe CSharp/docs/Fundamentals/8. Pointer Array.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Pointer Array | ||
|
||
```cs | ||
int** p = stackalloc int*[30]; | ||
int*** pp = stackalloc int**[10]; | ||
``` |