Use of unassigned local variable 'i'

This is a discussion on Use of unassigned local variable 'i' within the C# Programming forums, part of the General Programming Boards category; Code:
int i;
try
{
i = 0;
}
catch
{
}
if (i == 1)
{
}
This is ...

In theory, if the first line of your try block throws an exception it will reach your if condition without i being set to any specific value. So you need to set i in a way that it will always have a value even if exceptions are thrown.

If the only line in your try block is a line that you know for certain will never throw an exception, then why have a try block at all?

Seems like if you have something in a try block, one way the compiler might interpret this is, "Hey, the programmer is saying that this code might throw an exception at any point. I shouldn't depend on anything in the try block happening successfully." If you ask me, this is totally reasonable.

If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein

If you don't feel like initializing i to a value then you can always add a "finally" block after your catch block and set i to a value there. This way you can check the value of i later on for any of those values i might be assigned (whether in the try block, or finally block) and it will not produce an error.

Simply put, the compiler assumes that nothing inside a try..catch is guaranteed to have been executed; it's the same as if you set i inside an if statement. If you're really, really sure that i will always have a proper value set, then you can just declare it as int i = 0; or some other appropriate default, and ignore it.

In more realistic code, this is a warning to you that (in theory) not all code paths properly set the value. You may want to reconsider the design such that this can't happen. Granted, in your over-simplified code, there's no way for an assignment to throw and thus the hypothetical code-path that results in uninitialized code can't ever actually occur.

A lot of people find this annoying. But the compiler has to make sure that unassigned variables are not used. And that is the price you pay.

A better example would be

Code:

int i;
try {
i = 0;
} catch {
Application.Exit();
}
if (i == 0)
i++;

In any case, you can just initialize it and get it over with. The initialization doesn't seem "ugly", it is done in the same line, it is written on the end of the line, so it doesn't really take space. Thus, the initialization is a good solution.

My post was to demonstrate the issue. An oversimplification, which still showed the point, in a forum such as this, is more likely to yield useful comment then a cut and paste of the real world application I have the misfortune to be working with.

It is irritating that C# insists on "doing things for you" but in crude "general case" ways that don't match the real world.

Actually, ANY instance of this happening will come down to one of two scenarios, both of which are problems with how it was coded:

A) A code path exists where this value isn't set before it's used.
B) An unnecessary flow-control structure is being used.

In the case of a "real-world" try/catch, either the assignment line or any preceding line could throw, or those lines cannot. If one of the lines throws, then A) is true -- you have a code path where the value is unset. If none of those lines can ever throw, then B) is true -- you can pull this line and all preceding lines out of the try block, because they cannot raise exceptions and thus don't need to be inside the block.

I believe the only reasonable argument here, as shown in my example, is when the code forces the program to die with a function. The language can understand if you have a return statement, but has no idea what a function does.

But think that it would be kind of troublesome to "fix" the above. In my example, maybe Application.Exit() can fail and not terminate the program.

The real question here is this "Should it be a warning or an error?"

99% of the times, using unassigned variables in unacceptable. So what would you have done? Make it a simple warning?

I get the feeling of the question, been there myself, but always ask "what else could have been done?".