5

Consider the following code:

public unsafe struct MyStruct
{
    public fixed int Nums[128];
}

private static void DoSomething()
{
    MyStruct s = new MyStruct();

    unsafe
    {
        int val = s.Nums[23];
        Console.WriteLine(val.ToString()); //Is this guaranteed to be "0"?
    }
}

In this case, is it guaranteed that when a new MyStruct is created, the value of Nums at every index will be 0?

In my own testing, it appears like it does get initialized to the default, but I ask because it's unsafe.

2 Answers 2

5

Ahh ok this took some time to find,

However from the Language Specification Version 3.0

Starting at 18.7 Fixed size buffers and continuing further

There are several references, the most notable

Fixed size buffers are not subject to definite assignment checking (§5.3), and fixed size buffer members are ignored for purposes of definite assignment checking of struct type variables. When the outermost containing struct variable of a fixed size buffer member is a static variable, an instance variable of a class instance, or an array element, the elements of the fixed size buffer are automatically initialized to their default values (§5.2). In all other cases, the initial content of a fixed size buffer is undefined.

Now, i haven't tested this myself, and the language of these specs are sometimes hard to fully understand. However, this is seemingly consistent with your findings

Sign up to request clarification or add additional context in comments.

3 Comments

In my usage, don't none of those apply? s isn't a static variable and it's not in a class or array. What's the 'outermost containing struct variable' referring to?
@MineR the way i read it, is if you make MyStruct s a static variable or an instance variable it would be initialised to their defaults. However id be interested in your findings
I'm trying to find the answer to this question too. I'm trying to transparently replace an int with a structure I'm making. But I agree that the OP's example is one where the values would be undefined.
0

I was not able to find any updated or additional guidance in the updated spec apart from what TheGeneral posted here.

Starting at 18.7 Fixed size buffers and continuing further

There are several references, the most notable

Fixed size buffers are not subject to definite assignment checking (§5.3), and fixed size buffer members are ignored for purposes of definite assignment checking of struct type variables. When the outermost containing struct variable of a fixed size buffer member is a static variable, an instance variable of a class instance, or an array element, the elements of the fixed size buffer are automatically initialized to their default values (§5.2). In all other cases, the initial content of a fixed size buffer is undefined.

That said, I can confirm there is at least one situation--in .NET 6--in which the data in a fixed sized buffer may not be initialized. I just ran into this, and in my case, my struct was stored in a variable declared and new-ed within a for loop. On the first iteration, the struct's inner fixed sized buffer was clear as expected; however, each additional newing on subsequent iterations did absolutely nothing, so data accumulated, and several of my tests failed.

I found two ways to get the tests passing:

  1. Add a Clear method to my struct, and either call it after every new or add it to the struct's parameterless constructor.
  2. Delete the parameterless constructor from my struct, the existance of which was apparently preventing the buffer from being cleared.

I would pay close attention when the spec says something is undefined, and do not take chances. If you want the data to be clear, you should be sure to clear it yourself. Otherwise, you can never be certain that your code will work in every situation or that its behavior will not change significantly after an update.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.