1

Consider the following code:

public struct Color {
    public int R;
    public int G;
    public int B;
}

public class App
{
    static void Main()
    {
        Color c;
        c.B = 0xFF;
        int b = c.B;
    }
 }

csc compiles the code happily. I always thought all fields of a struct have to be assigned to before one can access data members of the struct. Is this a specialty of csc.exe?

I think NullReferenceExceptions are not the right solution, since we are talking about structs here.

Hamid Pourjam
  • 18,954
  • 8
  • 53
  • 67
Pachelbel
  • 523
  • 3
  • 11
  • Do you mean that you have to assign R,G and B before you can access any of these? If you don't specify any value for them they get initialized with default value based on their type so, even though you didn't initialize them, they have default values. – FCin Oct 16 '16 at 11:06
  • Without a specific constructor or field initializer, all fields of the structs are given their default value (0) and are therefore initialized. I think you're referring to the constraint placed when adding a custom constructor: inside such a constructor all fields have to be assigned before the constructor is exited (of course c itself still has to be initialized) – Me.Name Oct 16 '16 at 11:07
  • Possible duplicate of [What is a NullReferenceException, and how do I fix it?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – mybirthname Oct 16 '16 at 11:09
  • @Me.Name The thing is: if c.B = 0xFF is gone, the code is no longer valid. – Pachelbel Oct 16 '16 at 11:10
  • Ah, I see. Without creating and assigning an instance of Color, the space is reservered for the structure, but the fields are not assigned. The compiler will not allow you to use C directly or for example c.A, but since the address c.B is initialized, it is allowed to use only that field (`c.B` ). To be honest I didn't even know that was allowed. I wonder if that's documented behaviour – Me.Name Oct 16 '16 at 11:15

2 Answers2

3

From MSDN:

When you create a struct object using the new operator, it gets created and the appropriate constructor is called. Unlike classes, structs can be instantiated without using the new operator. In such a case, there is no constructor call, which makes the allocation more efficient. However, the fields will remain unassigned and the object cannot be used until all of the fields are initialized.

From MSDN:

Compiler Error CS0170: Use of possibly unassigned field 'field'. A field in a structure was used without first being initialized. To solve this problem, first determine which field was uninitialized and then initialize it before you try to access it.

From MSDN:

Compiler Error CS0165: Use of unassigned local variable 'name'. The C# compiler does not allow the use of uninitialized variables. If the compiler detects the use of a variable that might not have been initialized, it generates compiler error CS0165.


This is wrong:

I always thought all fields of a struct have to be assigned to before one can access data members of the struct

The correct one is:

All fields of a struct have to be assigned to before one can access the struct.


Color c;
c.B = 0xFF;
int b = c.B; // Okay. You have assigned B
int r = c.R; // Error CS0170! Use of possibly unassigned field
Color cc = c; // Error CS0165! Use of unassigned local variable. The object cannot be used until all of the fields are initialized
Hamid Pourjam
  • 18,954
  • 8
  • 53
  • 67
  • "the object cannot be used" - you mean this does not refer to accessing a data member of the struct? – Pachelbel Oct 16 '16 at 11:26
  • The data member(`B`) is initialized since you have `c.B = 0xFF;` . You can not access other members such as `R` and `G` because they are not initialized. – Hamid Pourjam Oct 16 '16 at 11:27
  • but this does not seem to be indicated in your citation from MSDN. The thing is that I'd like to have this behaviour "backed" up by the spec. – Pachelbel Oct 16 '16 at 11:30
  • Ok, so maybe the compiler is a little more flexible than the actual spec. thanks! – Pachelbel Oct 21 '16 at 12:34
0

Refer this link

msdn ink

If you use Color c; fields are not initialized, but if you do Color c = new Color(); all fields will be initialized.

if you run the below code. it will failed to compile.

    Color c;
    int b = c.B;

But this will be compiled.

       Color c = new Color();
       // c.B = 0xFF;
        int b = c.B;
vivek nuna
  • 12,695
  • 7
  • 48
  • 123
  • Yes, my (subtle ;-) point is though that you do not require the new-operator (although it is of course often bad style not to use it). however, you can read fields here before all of them are initialized. – Pachelbel Oct 16 '16 at 11:13