Why does the compiler require local variables to be initialized and fields not?

Asked

Viewed 489 times

18

The question Why a variable with default value is usually declared? addresses the question of whether or not to initialize a variable before using it.
However this option becomes mandatory when it comes to a local variable.

A field is automatically initialized with 0, if it is a primitive type, or null, in the case of a type per reference.

Local variables not initialized if used, compiler displays error:

Use of unassigned local variable 'x'

What is the reason for this difference in behavior?

  • Look, people can answer whatever they want, but at the end of the day it’s like this for a design decision of Anders Rejlsberg. He probably did it to follow the C++ pattern, but then the question becomes why C++ does it.

  • It’s good to point out that it’s not a bug, but a warning. I think the compiler can compile,?

  • 1

    It’s not a warning. It’s a mistake.

  • Depends. If you try to use the variable gives error, otherwise it is only a warning (of unused variable).

  • @But Renan is a mistake, q makes the nonsense bigger

  • 1

    @Renan the "unused variable" warning happens regardless be local or field.

Show 1 more comment

1 answer

13


I couldn’t use it better reference than Eric Lippert:

  • Use null in a local context most likely is a bug, and in this context it is easy for the compiler to detect and inform.

    I disagree somewhat with that. A notification would be great, a Warning is acceptable, but a mistake, for me, is something that the compiler should not issue, within the current philosophy of C#. I even like it, hate it null, I’m just saying it’s inconsistent. I consider it a team mistake have decided that the compiler does this, but it’s just my opinion. They decided so and we can only follow. Even Eric’s response shows that they use heuristics that can generate wrong results. This is not something a compiler should do for errors and even alerts.

  • A field has a reasonable chance of being what it wanted, at least temporarily.

    Or it was in the past, today has facilities and has not been so true so, has approached a little the probability of local use, but still has possibility of the null be the desired one. And the compiler would have difficulties analyzing it by much broader context. They considered that not worth the effort.

    But note that the language does not force anything anyway. There is no way to do it. Even in specification, it is impossible. There are always paths that make this verification undecidable, and Eric’s response shows that.

So the decision to put in the compiler was by liking the developers justifying with the probability to hit ally with the ease to carry out.

At the end of his reply, the options were placed:

  • Making a common, safe and often used language illegal
  • Perform a very extensive analysis making the compilation take even hours to try to discover a bug that might not even be there
  • Adopt a default value and stay like this

They picked the last.

My restriction is that they didn’t do the same to the locals.

But what I really wanted was for you not to have null. What they say was the biggest mistake in the language and they partly solved in C# 8.

I could not find a better reason to error in the use of the local variable not initialized. I understand their motive perfectly, it makes sense, but it gets a little crooked. It has one more reply from him that speaks something about the subject. Ali confirms that all variables are initialized, even if the null is not accepted as valid value in local context. Hans talks about it too.

Note that the variable can be initialized later.

If they decide to eliminate this error one day does not change something for the codes, compile everything existing today without changing any semantics. So it should not be a mistake. Error is for what never works, error is what is certainly a mistake.

To the CLR the method may require initialization or not, remember that the CLR runs other languages, such as C++ for example, which does not initialize. This is done with the marking of CIL .locals init. This does not restrict whether it is type by reference or not. This marking indicates that the stack frame of that method shall be cleaned, zeroed, therefore reference types shall have value null.

  • 1

    I agree with you. In short, the discussion (I imagine) will have been like this: It did not initialize and used -> almost certainly is mistake -> so let’s "give error" -> Ops! but how to detect this in the case of fields? -> It is not easy, no, however in the case of locations it is simple -> OK, let’s just do in the case of locations. Then they went home convinced they did a good job(I’m not judging).

  • @ramaral exactly this.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.