5

Why does taking the address of a variable eliminate the "Use of unassigned local variable" error?

(Why can we take the address without initialization in the first place?)

static unsafe void Main() { int x; int* p = &x; //No error?! x += 2; //No error?! } 
8
  • Title is not for tags, you know, don't you?:) Commented May 19, 2011 at 6:41
  • @abatishchev: Yeah I know, but I thought it would be helpful anyway. Though thanks for the edit nevertheless. :) Commented May 19, 2011 at 6:42
  • 1
    The second part of your question, why can we take the address, is easy: Because the variable has an address whether you've assigned a value to it or not. But it's interesting that the compiler then considers x initialized... Commented May 19, 2011 at 6:43
  • THis seems to me to be C++ code, not C# Commented May 19, 2011 at 6:43
  • 4
    @Flawless if C++ required you to say whenever you were being unsafe then C++ programs would be a lot longer :) Commented May 19, 2011 at 6:47

2 Answers 2

7

C# Language spec, section 18.5.4:

The & operator does not require its argument to be definitely assigned, but following an & operation, the variable to which the operator is applied is considered definitely assigned in the execution path in which the operation occurs. It is the responsibility of the programmer to ensure that correct initialization of the variable actually does take place in this situation.
...
The rules of definite assignment for the & operator exist such that redundant initialization of local variables can be avoided. For example, many external APIs take a pointer to a structure which is filled in by the API. Calls to such APIs typically pass the address of a local struct variable, and without the rule, redundant initialization of the struct variable would be required.

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

8 Comments

O.M.G... so they weren't kidding about the "unsafe" in unsafe blocks!
I do have to note: looking further at the disassembly, seems like the CLR initializes the variable anyway, with .locals init. So maybe it's not so unsafe after all...
@Mehrdad: It looks like I didn't read far enough; the spec does give a rationale for the rule. See the paragraph I added.
@Gabe: Interesting. But now it begs the question, so what? What's wrong with redundant initialization?
@Mehrdad: What's wrong with it? Well, it's redundant. And everything that's redundant can and should be avoided :) When you're programming in native languages like C and C++, you learn to leave stuff away that you don't need. Or as C++ says.. you only pay for what you use.
|
2

I think because, once you've taken a pointer to the variable, there's no way for the compiler to analyze whether a value is assigned via that pointer, so it's excluded from the definite assignment analysis.

4 Comments

@Damien: Okay sure, but why doesn't it force me to initialize it first? Isn't it better safe than sorry?
@Merhdad - because you're going off-road with unsafe code - maybe you need every ounce of performance out of this piece of code - so the compiler forcing you to perform additional work would be bad.
@Rick: Doesn't the C++ compiler give an error when it sees unsafe?
@Gabe: I asked myself, if Damien's theory is correct, then the equivalent C++ code will also not give a warning with the C++ compiler. It also has the same problem once an address is taken. So the essential code is the indented portion. That's what I tested.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.