0

Unsafe Code in C# (unsafe keyword)

 2 years ago
source link: https://code-maze.com/unsafe-code-csharp/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Unsafe Code in C# (unsafe keyword)

Publisher Logo

We value your privacy

We and our store and/or access information on a device, such as cookies and process personal data, such as unique identifiers and standard information sent by a device for personalised ads and content, ad and content measurement, and audience insights, as well as to develop and improve products.With your permission we and our partners may use precise geolocation data and identification through device scanning. You may click to consent to our and our partners’ processing as described above. Alternatively you may click to refuse to consent or access more detailed information and change your preferences before consenting.Please note that some processing of your personal data may not require your consent, but you have a right to object to such processing. Your preferences will apply to this website only. You can change your preferences at any time by returning to this site or visit our privacy policy.

Unsafe Code in C# (unsafe keyword)

Posted by Code Maze | Updated Date Jul 11, 2022 | 0

Code Maze Book Collection

Want to build great APIs? Or become even better at it? Check our Ultimate ASP.NET Core Web API program and learn how to create a full production-ready ASP.NET Core API using only the latest .NET technologies. Bonus materials (Security book, Docker book, and other bonus files) are included in the Premium package!

In this article, we are going to learn about the unsafe code in C#.

In general, the codethat we write in C# is safe code. It creates managed objects and doesn’t access the memory directly. On the other hand, unsafe code in C# is code that is not in direct control of the Common Language Runtime (CLR). Regardless of how the word ‘unsafe’ makes it sound, it is not inherently dangerous to write unsafe code. However, the CLR would not be able to verify the safety of the code i.e. type safety, pointer errors, and so on. 

To download the source code for this article, you can visit our GitHub repository.

To understand unsafe code and where it comes into the picture, we’ll have to understand managed and unmanaged code in C#.

Let’s dive in.

What is Managed Code?

Managed code is code whose execution is managed by a runtime. In the case of .NET, this runtime is called Common Language Runtime. We use high-level languages like C#, F#, Visual Basic, etc. to write managed code. The respective compiler then converts this code into a binary of Intermediate Language (IL). 

The CLR takes this IL code,  converts it into machine code using a method called Just-In-Time compiling, and executes it. The runtime is also in charge of memory management, type safety, security considerations, etc. thus effectively managing the code.

What is Unmanaged Code?

Unmanaged code is any code written outside of the .NET framework. A program written in C/C++ is an example of unmanaged code. As the CLR has no control over unmanaged code, we’re responsible for almost everything like memory management i.e. memory allocation, as well as deallocation when the work is done, and security practices.

A program written in unmanaged code is essentially ready to load into the operating system memory and start executing.

Now that we understand the distinction between managed and unmanaged code, let’s take a look at unsafe code.

Unsafe Code

C# supports an unsafe context where we can write code whose security is unverifiable by the CLR. For example, by default, C# does not support pointer arithmetic to ensure type safety and security. However, in an unsafe context, we can use pointers.

To denote an unsafe context in C#, we use the unsafe keyword. As the CLR can’t verify the safety of unsafe code, it only allows unsafe code execution within a fully trusted assembly.

Running Unsafe Code

Let’s create a simple program to look at the usage of the unsafe keyword: 

unsafe static void Main(string[] args)
var number = 100;
int* numberPtr = &number;
Console.WriteLine("The value of variable: {0}", number);
Console.WriteLine("The value of variable using pointer: {0}", numberPtr->ToString());
Console.WriteLine("The address of variable : {0}", (int)numberPtr);
Console.ReadLine();
unsafe static void Main(string[] args)
{
    var number = 100;
    int* numberPtr = &number;

    Console.WriteLine("The value of variable: {0}", number);
    Console.WriteLine("The value of variable using pointer: {0}", numberPtr->ToString());
    Console.WriteLine("The address of variable : {0}", (int)numberPtr);
    Console.ReadLine();
}

In the above code, we have declared a pointer variable numberPtr, denoted by int*. Unlike a normal variable that stores a value of any type (int, char, string, etc.), it stores a memory address. We provide this memory address using the address-of operator (&). The address-of operator returns the address of the variable number

Here, we are trying to print the location as well as the value of the variable from the location referenced by the pointer variable.

However, this code does not compile. This is because we need to specify the AllowUnsafeBlocks compiler option in order to compile code that uses unsafe keyword.

To do this, we need to go to project properties by selecting Project > {Project Name} Properties option. We can then enable the “Allow code that uses the ‘unsafe’ keyword to compile.” option.

As an alternative, we can mark AllowUnsafeBlocks as true in the csproj file of the project:

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>		
        <AllowUnsafeBlocks>True</AllowUnsafeBlocks>
    </PropertyGroup>
</Project>

This allows our code to compile and execute to return an output:

The value of variable: 100
The value of variable using pointer: 100
The address of variable : 366470540
The value of variable: 100
The value of variable using pointer: 100
The address of variable : 366470540

Usage of the unsafe Keyword

In the previous example, we learned that we can use the unsafe keyword for the Main() function and write unsafe code inside it.  Let’s look at other usages of the unsafe keyword.

Unsafe Block

Instead of using the unsafe keyword for the complete Main() function, we can also use it for a block of code:

public static void Main(string[] args)
unsafe
var number = 100;
int* numberPtr = &number;
Console.WriteLine("The value of variable: {0}", number);
Console.WriteLine("The value of variable using pointer: {0}", numberPtr->ToString());
Console.WriteLine("The address of variable : {0}", (int)numberPtr);
Console.ReadLine();
public static void Main(string[] args)
{
    unsafe
    {
        var number = 100;
        int* numberPtr = &number;

        Console.WriteLine("The value of variable: {0}", number);
        Console.WriteLine("The value of variable using pointer: {0}", numberPtr->ToString());
        Console.WriteLine("The address of variable : {0}", (int)numberPtr);
    }

    Console.ReadLine();
}

The above code is similar to our previous example, with the only difference being the use of unsafe keyword for a block of code instead of the Main() function. The output remains the same:

The value of variable: 100
The value of variable using pointer: 100
The address of variable : -1940395892
The value of variable: 100
The value of variable using pointer: 100
The address of variable : -1940395892

Unsafe Member Declaration

We can also use unsafe keyword in the declaration of a member function. The entire context of such a member function is suitable for use of unsafe code:

public static unsafe void GetTriple(int* num)
*num = *num * 3;
public static unsafe void GetTriple(int* num)
{
    *num = *num * 3;
}

We can then call this method by passing a pointer variable as the parameter:

public static unsafe void Main(string[] args)
var num = 10;
int* numPtr = &num;
Console.WriteLine("GetTriple Input: {0}", num);
GetTriple(numPtr);
Console.WriteLine("GetTriple Output: {0}", num);
Console.ReadLine();
public static unsafe void Main(string[] args)
{
    var num = 10;
    int* numPtr = &num;

    Console.WriteLine("GetTriple Input: {0}", num);

    GetTriple(numPtr);
            
    Console.WriteLine("GetTriple Output: {0}", num);
    Console.ReadLine();
}

And the output:

GetTriple Input: 10
GetTriple Output: 30
GetTriple Input: 10
GetTriple Output: 30

Pointer to Access Array Elements

The array and a pointer to a data type with the same array data are not considered the same variable types in C#. So, char[] and char* are not the same types. However, we can access array elements using pointers:

public static unsafe void Main(string[] args)
var text = "Happy";
fixed (char* textPtr = text)
for (var i = 0; i < text.Length; i++)
Console.WriteLine("text[{0}] : {1}", i, *(textPtr + i));
Console.ReadLine();
public static unsafe void Main(string[] args)
{
    var text = "Happy";

    fixed (char* textPtr = text)
    {
        for (var i = 0; i < text.Length; i++)
        {
            Console.WriteLine("text[{0}] : {1}", i, *(textPtr + i));
        }
    }

    Console.ReadLine();
}

In the above example, we have also used fixed statement. It prevents a movable variable from relocation by the garbage collector. The fixed statement can only be used in an unsafe context. 

It sets the pointer to a managed variable and “pins” it on the heap to disallow it from moving unpredictably. Hence in the example, the textPtr pointer points to the start of the array using the fixed statement.

Now, we know the various usages of the unsafe keyword. Let’s take a look at when we use unsafe code and the advantages and disadvantages associated.

Why Do We Need Unsafe Code in C#?

We use unsafe code if we need to use pointers. However, we rarely need to use pointers in C# apart from some situations that warrant their use.

The most common application is calling into native code from C# to invoke structures with pointers in them. Sometimes, in performance-critical code, using pointers may also lead to performance enhancement and the unsafe context can be used in those scenarios too. 

It is essential that we avoid using unsafe code unless necessary as it may lead to various pitfalls. 

As the unsafe code can be executed only from an entirely trusted context, it might prove challenging to run from say, a network not configured to be trusted. It introduces several issues like buffer overruns, code not being type-safe, fragmentation of managed heap while pinning the managed variable so that the pointer can access it, and so on.

This also has maintainability repercussions. The code becomes harder to understand and maintain for programmers not used to the unsafe approach.

Difference Between Unsafe and Unmanaged Code

Unmanaged code runs outside the context of CLR. It is not managed by the runtime and hence not visible to the garbage collector. For example, the calls to C/C++ dlls.

Whereas the unsafe code still runs under the context of CLR, it just allows us the use of pointers for direct memory access. It is code outside the verifiable subset of Common Intermediate Language (CIL).

Conclusion

In this article, we’ve learned about the unsafe code in C# and various usages of the “unsafe” keyword. We’ve also learned about when to use unsafe code in our programs, along with their advantages, and disadvantages. 

Code Maze Book Collection

Want to build great APIs? Or become even better at it? Check our Ultimate ASP.NET Core Web API program and learn how to create a full production-ready ASP.NET Core API using only the latest .NET technologies. Bonus materials (Security book, Docker book, and other bonus files) are included in the Premium package!

Share:

Subscribe
guest
Label
0 Comments
booklet-200px-width-min.png

--- FREE eBook ---
Top 16 BEST PRACTICES
to improve API effectiveness 10x.
Find out how!

Leave this field empty if you're human:

© Copyright code-maze.com 2016 - 2022

wpDiscuz


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK