Why aren't unassigned local variables automatically initialized?

前端 未结 6 1570
长发绾君心
长发绾君心 2021-01-02 06:28

It seems like there is no way to have unassigned local variables in your code or check for them, as the compiler spits out Use of unassigned local variable erro

相关标签:
6条回答
  • 2021-01-02 06:58

    1 Why does the compiler not allow the use of uninitialized variables?

    Because preventing that promotes good programming.

    2 Why does the compiler allow the use of uninitialized class members?

    Because it's not possible to track this with any accuracy.

    0 讨论(0)
  • 2021-01-02 07:01

    I see you've updated your question, so I'll update my answer. Your question has two parts, one relating to local variables and the other to instance variables on a class instance. First, however, this isn't really a compiler design decision, but rather a language design decision.

    Spec Section 12.3.1/12.3.2

    Local Variables

    We know why you can define a variable without giving it a value. One reason, an example of something like this:

    int x;
    // do stuff
    x = 5;  // Wow, I can initialize it later!
    Console.WriteLine(x);
    

    The standard defines why this is valid code. Now, I'm not on the C# design team, but it makes good sense why they wouldn't automatically initialize the code for you (besides the performance hit when you actually didn't want it to be automatically initialized).

    Say the code above was your intention, but you forgot to initialize x = 5;. If the compiler had automatically initialized the variable for you, the code would compile, but it would do nothing like you would expect.

    Granted this is a trivial example, but this was a very good design decision from the language designers, as it would save many headaches trying to figure out why something wasn't working as expected.

    As a side note, I can't think of a reason why you would want to define the code without assigned something to it, or use the default value (in every case), to me that would likely be a bug, which I'm sure is what the compiler designers may have determined.

    Class Instance Variables

    Class level members are defined by the standard to be initially assigned. In fact, to be fair, local variables outside those declared in a catch, foreach or using statement are initially unassigned. So really, this is a standards issue, not a compiler issue.

    If I were to try and guess why this is the case with regards to instance variables of class instances, I would say it has to do with how the memory is allocated on the heap, since that is where the classes are allocated. When a class is allocated on the heap, all of its members have to be initialized and allocated on the heap with it. It's not just ok to do it in a class member than a local variable, it has to be done this way. They simply cannot be left unassigned.

    0 讨论(0)
  • 2021-01-02 07:03

    C# is a "pit of success" language.

    This is a design decision, as the language is completely capable of allowing you to use locals that have not been explicitly assigned. However, it is normally true that usage of such variables is erroneous, that a code path has not set a value for some reason. To avoid such errors, the compiler requires that all locals be assigned before being used.

    0 讨论(0)
  • 2021-01-02 07:06

    Consider the following code:

    void blah(IDictionary<int,int> dict)
    {
      for (int i=0; i<10; i++)
      {
        if ((i & 11) != 0)
        {
            int j;
            dict.TryGetValue(i, out j);
            System.Diagnostics.Debug.Print("{0}",j);
            j++;
        }
      }
    }
    

    Suppose that the TryGetValue method of the passed-in implementation of IDictionary<int,int> never actually writes to j [not possible if it's written in C#, but possible if it's written in another language]. What should one expect the code to print?

    Nothing in the C# standard requires that j be maintained when code leaves the if statement, but nothing requires that it be reset to zero between loop iterations. Mandating either course of action would impose additional costs in some cases. Rather than doing either, the Standard simply allows that when TryGetValue is called, j may arbitrarily hold zero or the last value it held when it was in scope. Such an approach avoids unnecessary costs, but would be awkward if code were allowed to see the value of j between the time it re-enters scope and the time it is written (the fact that passing an uninitialized variable as an out parameter to code written in another language will expose its value was likely unintentional).

    0 讨论(0)
  • 2021-01-02 07:13

    By taking your suggestion of initializing reference types to null, instead of the current behavior (buggy code causes a compile time error), you'll instead get a runtime error when you dereference an uninitialized variable. Is that really what you want?

    0 讨论(0)
  • 2021-01-02 07:21

    Because what do you want in there? you want x to be zero by default and I want it to be 5...

    if they assign 0 to int(s) and all the world starts assuming so, then they will change to -1 at some point and this will break so many applications around the globe.

    in VB6 variables were assigned to something by default I think, and it was not as good as it seemed to be.

    when you use C#, or C++, you assign the value with what you want, not the compiler for you.

    0 讨论(0)
提交回复
热议问题