The Unsafe Keyword In C#

The Unsafe Keyword

What is the unsafe keyword in C#? When should you use it? Should you use it?

It’s not one of the most common used keywords in your generally C# application but I wanted to talk about it in this article. It could be the answer to your current problem - or you may have just gone through some code, found it and wondered what it is used for.

What is unsafe keyword in C#?

Unsafe is a C# programming language keyword that is used to denote a section of code that is not managed by the .Net Framework Common Language Runtime (CLR). Unsafe is used to declare a block of code or member where some or all of the code that is considered to be unmanaged code.

Microsoft’s pages refer to the unsafe keyword as: denotes an unsafe context, which is required for any operation involving pointers.

Coming from a background in C++, having any keyword that you have to use to denote pointers is strange; though the user of pointers is not a strange context. Pointers are a common things in C++; but for C# - pointers are generally, in most cases at least, never used.

In fact, I would suspect many of those developing in C# don’t even realize that there is some pointer functionality available.

Can we use pointers in C#?

To maintain security and type safety, C# does not support pointer arithmetic: at least not by default. Using the unsafe keyword; you can define an unsafe context in code in which pointers can be used.

Using pointers in C# is where we start to use unmanaged code: code that is outside the context of the .Net Framework CLR.

C# unsafe struct

If we can use pointers in C#, does this mean we can define an unsafe struct. You can use the unsafe keyword when defining a struct to define the entire struct as unsafe in context. This will allow you to use pointers in your struct.

The following example uses unsafe to define two pointers in the struct. This example shows how to define a double linked list structure in C#.

C#
public unsafe struct LList
{
    public int Value;
    public LList* next;
    public LList* previous;
}

Using the unsafe keyword it is completely possible to create an unsafe struct in this manner. In this example above then entire struct is classified as unsafe - however, this could be re-written as follows:

C#
public struct LList
{
    public int Value;
    public unsafe LList* next;
    public unsafe LList* previous;
}

In this example, only the field declarations for left and right fall into the unsafe context.

C# unsafe methods

In this article we’ve shown that you can use the unsafe keyword to define an unsafe field/variable and an unsafe struct - so can we use them to define an unsafe method?

Unsafe is a keyword that is added to modify a field or block of code to define it as unsafe context. As this is true; it can be added to a method to mark all code in that method as unsafe (similar to how we used it for struct).

The following would define a method where all the code is in the unsafe context.

C#
{ ...
    public unsafe LList* findValue(LList* in, int value)
    {
        // Do your stuff here
        LList *output = null;
        while(in->next != null)
        {
            if(in->value == value)
            {
                output = in;
                break;
            }
            
            // Step through the list
            in = in->next;
        }
        
        return output;
    }
}

Using the unsafe keyword as a modifier to the method declaration tells the compiler that the entire content of the method falls into the unsafe context.

Unsafe block of code

Instead of creating an entire method that falls into the unsafe context, you can create an unsafe block of code.

C#
Static void main()
{
    int valueToFind = 10;
    unsafe 
    {
        LList *aList = setupList(); // Method used to setup values in the list
        
        findValue(aList, valueToFind);
    }
}

This method uses an unsafe block of code for when it needs to create a pointer to some list in memory and then pass that to the unsafe method findValue.

One great reference you may want to check out is a page over at Microsoft on Unsafe code. This gives more details on the unsafe keyword and what you can do with it.

Should we use the unsafe keyword in C#

We have the unsafe keyword available to us in C# but should we use it?

My personal thought is this: for most coding problems the answer is no. Pointers and pointer arithmetic were left out of C#, and many other languages, on purpose I believe.

Having access directly to memory causes problems when misused. I’ve personally seen code in C/C++ that has access memory that had been previous reallocated or was out of scope.

This caused issues with the applications and could result in major problems.

Using managed code; not having access directly to memory; means less of these issues. Not accessing unallocated memory. Not trying to get values or update values causing unknown results.

That said, there are some valid reasons I could see for using unsafe pointers. When you create a string in C# its set to a value and is immutable. If you wanted to change some part of that string; say from “king” to “sing”; then you have to in C# you would first assign “king” to the string object.

C#
string value = "king";


Then when you wanted to change it to “sing”, you would assign it that value

C#
value = “sing”;

However, this is not changing the value in memory of the variable. Stepping through the process. First, a string object value is created and assigned the value “king”

Next, we assign the value “sing” to the value object. However, because it is immutable it doesn’t change the value in the memory location it is holding the value “king” in; it creates a whole new string object and assigns the value “sing” to it.

Using the unsafe keyword you could create a pointer, in theory, to the value object memory and change the value held in that memory location instead of creating a new string object.

That said, this is where the coding issues could come in place. You could try and assign a value that is too big for that memory to hold (say a 5 character string instead of 4) and you would get undefined problems.

It is far better to not us unsafe in this situation; continue with managed code and know that you are not potentially adding problems. However, you may find that reading from memory directly using pointers could be quicker than managed object methods.

However, I would still say - do not use the unsafe keyword unless you know what you are doing and face an issue that can only be answered by directly accessing memory through pointers.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram