473,598 Members | 3,029 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Use of unassigned local variable?

In the following example, c# 2.0 compiler says that a3 and ret are used
before assigned.
as far as I can see, definite assignment is made.

If I add

finally
{
ret = true;
a3 = "b3";
}

it compiles OK.

------ example -------
using System;
using System.Collecti ons.Generic;
using System.Text;

namespace Scope
{
class Program
{
static void Main(string[] args)
{
string test;
Try(out test);
}

private static bool Try(out string Hello)
{
bool ret;
string a1, a2, a3;

try
{
for (int i = 0; i < 3; i++)
{
a1 = "1";
a2 = i.ToString() + a1;
a3 = "HELLO";
}

ret = true;
}
catch (Exception)
{
a3 = "sa";
}

Hello = a3;

return ret;
}

}
}
Jan 26 '07 #1
22 8403
Because there is a path through the method where the variable ret is not
assigned (bad form to call a method Try(), by the way).

If an exception is raised in the first try{} block, execution goes to the
catch block, where a3 is assigned. Execution then falls through to the code
after the catch and you try to return ret before it's been assigned.

Can't be bothered to look for a3.

A finally{} block is always executed - so that's bound to fix it. You could
always cure it by initialising your variables, of course, either with
initialisers or in the constructor.

HTH
Peter
"Laura T." <LT@NOWHERE.COM wrote in message
news:es******** ******@TK2MSFTN GP04.phx.gbl...
In the following example, c# 2.0 compiler says that a3 and ret are used
before assigned.
as far as I can see, definite assignment is made.

If I add

finally
{
ret = true;
a3 = "b3";
}

it compiles OK.

------ example -------
using System;
using System.Collecti ons.Generic;
using System.Text;

namespace Scope
{
class Program
{
static void Main(string[] args)
{
string test;
Try(out test);
}

private static bool Try(out string Hello)
{
bool ret;
string a1, a2, a3;

try
{
for (int i = 0; i < 3; i++)
{
a1 = "1";
a2 = i.ToString() + a1;
a3 = "HELLO";
}

ret = true;
}
catch (Exception)
{
a3 = "sa";
}

Hello = a3;

return ret;
}

}
}


Jan 26 '07 #2
Thanks Peter,

in the catch block both ret and a3 are assigned. They have the same flow.
Only a3 is shown as unassigned, ret not.
I still think there is something strange. IF I change the function (yes, bad
choice for the name) to this:

private static bool Try(out string Hello)
{
bool ret;
string a1, a2, a3;

try
{
for (int i = 0; i < 3; i++)
{
a1 = "1";
a2 = i.ToString() + a1;
a3 = "HELLO";
}
ret = true;
}
catch (Exception)
{
ret = true;
a3 = "sa";
}

Hello = a3;

return ret ==true;
}

a3 is still unassigned to the compiler. IMHO both ret and a3 are assigned
definetly (it has catch all), and in any case, as they both have the same
flow, I'd at least expect that it would complain on both cases. Ok, there is
a ret=true, but it does not get executed if i.tostring() would throw. If I
comment it out, then compiler says that both ret and a3 are unassigned. If I
add a3="HELLO"; after ret=true; I get no errors.


"Peter Bradley" <pb******@uwic. ac.ukha scritto nel messaggio
news:%2******** ********@TK2MSF TNGP06.phx.gbl. ..
Because there is a path through the method where the variable ret is not
assigned (bad form to call a method Try(), by the way).

If an exception is raised in the first try{} block, execution goes to the
catch block, where a3 is assigned. Execution then falls through to the
code after the catch and you try to return ret before it's been assigned.

Can't be bothered to look for a3.

A finally{} block is always executed - so that's bound to fix it. You
could always cure it by initialising your variables, of course, either
with initialisers or in the constructor.

HTH
Peter
"Laura T." <LT@NOWHERE.COM wrote in message
news:es******** ******@TK2MSFTN GP04.phx.gbl...
>In the following example, c# 2.0 compiler says that a3 and ret are used
before assigned.
as far as I can see, definite assignment is made.

If I add

finally
{
ret = true;
a3 = "b3";
}

it compiles OK.

------ example -------
using System;
using System.Collecti ons.Generic;
using System.Text;

namespace Scope
{
class Program
{
static void Main(string[] args)
{
string test;
Try(out test);
}

private static bool Try(out string Hello)
{
bool ret;
string a1, a2, a3;

try
{
for (int i = 0; i < 3; i++)
{
a1 = "1";
a2 = i.ToString() + a1;
a3 = "HELLO";
}

ret = true;
}
catch (Exception)
{
a3 = "sa";
}

Hello = a3;

return ret;
}

}
}



Jan 26 '07 #3
Hi Laura,

Indeed, a3 is always assigned in your code as well is ret. The
difference is that you assign a3 in the for loop. Possible the compiler
does not "see" it :) There are lots of situations like this, but in
dotNet it is not a warning, but an error. In this case you could assign
null or so when declaring it to make the compiler happy :)

--
rgds, Wilfried [MapPoint MVP]
http://www.mestdagh.biz

Laura T. wrote:
Thanks Peter,

in the catch block both ret and a3 are assigned. They have the same flow.
Only a3 is shown as unassigned, ret not.
I still think there is something strange. IF I change the function (yes, bad
choice for the name) to this:

private static bool Try(out string Hello)
{
bool ret;
string a1, a2, a3;

try
{
for (int i = 0; i < 3; i++)
{
a1 = "1";
a2 = i.ToString() + a1;
a3 = "HELLO";
}
ret = true;
}
catch (Exception)
{
ret = true;
a3 = "sa";
}

Hello = a3;

return ret ==true;
}

a3 is still unassigned to the compiler. IMHO both ret and a3 are assigned
definetly (it has catch all), and in any case, as they both have the same
flow, I'd at least expect that it would complain on both cases. Ok, there is
a ret=true, but it does not get executed if i.tostring() would throw. If I
comment it out, then compiler says that both ret and a3 are unassigned. If I
add a3="HELLO"; after ret=true; I get no errors.


"Peter Bradley" <pb******@uwic. ac.ukha scritto nel messaggio
news:%2******** ********@TK2MSF TNGP06.phx.gbl. ..
>Because there is a path through the method where the variable ret is not
assigned (bad form to call a method Try(), by the way).

If an exception is raised in the first try{} block, execution goes to the
catch block, where a3 is assigned. Execution then falls through to the
code after the catch and you try to return ret before it's been assigned.

Can't be bothered to look for a3.

A finally{} block is always executed - so that's bound to fix it. You
could always cure it by initialising your variables, of course, either
with initialisers or in the constructor.

HTH
Peter
"Laura T." <LT@NOWHERE.COM wrote in message
news:es******* *******@TK2MSFT NGP04.phx.gbl.. .
>>In the following example, c# 2.0 compiler says that a3 and ret are used
before assigned.
as far as I can see, definite assignment is made.

If I add

finally
{
ret = true;
a3 = "b3";
}

it compiles OK.

------ example -------
using System;
using System.Collecti ons.Generic;
using System.Text;

namespace Scope
{
class Program
{
static void Main(string[] args)
{
string test;
Try(out test);
}

private static bool Try(out string Hello)
{
bool ret;
string a1, a2, a3;

try
{
for (int i = 0; i < 3; i++)
{
a1 = "1";
a2 = i.ToString() + a1;
a3 = "HELLO";
}

ret = true;
}
catch (Exception)
{
a3 = "sa";
}

Hello = a3;

return ret;
}

}
}


Jan 26 '07 #4
On Jan 26, 12:07 pm, "Laura T." <L...@NOWHERE.C OMwrote:
Thanks Peter,

in the catch block both ret and a3 are assigned. They have the same flow.
Only a3 is shown as unassigned, ret not.
I still think there is something strange. IF I change the function (yes, bad
choice for the name) to this:

private static bool Try(out string Hello)
{
bool ret;
string a1, a2, a3;

try
{
for (int i = 0; i < 3; i++)
{
a1 = "1";
a2 = i.ToString() + a1;
a3 = "HELLO";
}
ret = true;
}
catch (Exception)
{
ret = true;
a3 = "sa";
}

Hello = a3;

return ret ==true;
}

a3 is still unassigned to the compiler. IMHO both ret and a3 are assigned
definetly (it has catch all), and in any case, as they both have the same
No, because the compiler can't be sure that the code inside the for
loop will be executed so there is a chance that you might exit the try
block without assigning a3. Suppose your for loop used a variable as
the upper limit instead of a number:

for (int i = 0; i < SomeVar; i++)

Since the compiler does not know the value of SomeVar at compile time,
it can't be sure that the for loop will be entered so that a3 can be
assigned.

I think this is why it is complaining, because there is a path through
the code in which it is possible for a3 to remain unassigned when it
reaches the line where you are using its value to assign to the Hello
variable.

Jan 26 '07 #5
Laura T. <LT@NOWHERE.COM wrote:

<snip>
a3 is still unassigned to the compiler. IMHO both ret and a3 are assigned
definetly (it has catch all), and in any case, as they both have the same
flow, I'd at least expect that it would complain on both cases. Ok, there is
a ret=true, but it does not get executed if i.tostring() would throw. If I
comment it out, then compiler says that both ret and a3 are unassigned. If I
add a3="HELLO"; after ret=true; I get no errors.
ret is definitely assigned at the end of the try block - a3 isn't. You
see, the compiler doesn't see the difference between:

for (int i = 0; i < 3; i++)
{
a1 = "1";
a2 = i.ToString() + a1;
a3 = "HELLO";
}

and

for (int i = 10; i < 3; i++)
{
a1 = "1";
a2 = i.ToString() + a1;
a3 = "HELLO";
}

Note how it will never enter the main part of the block in the second
example. The compiler doesn't check that the condition of the for loop
is always true for the first iteration, and thus make a1-a3 definitely
assigned because of it.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jan 26 '07 #6
Hi Chris,

Thanks for your comments.
for (int i = 0; i < SomeVar; i++)

Since the compiler does not know the value of SomeVar at compile time,
it can't be sure that the for loop will be entered so that a3 can be
assigned.
In this case, I would agree, because SomeVar is not constant. But my example
loop, for (int i = 0; i < 3; i++), is explicitly local and "constant".
Compiler should have no trouble teven to unroll the loop since it has no
other constraints than the constant 3.
When the compiler checks that the condition is bool it could also do rest of
the analysis, no?

LT

"Chris Dunaway" <du******@gmail .comha scritto nel messaggio
news:11******** *************@v 33g2000cwv.goog legroups.com...
On Jan 26, 12:07 pm, "Laura T." <L...@NOWHERE.C OMwrote:
>Thanks Peter,

in the catch block both ret and a3 are assigned. They have the same flow.
Only a3 is shown as unassigned, ret not.
I still think there is something strange. IF I change the function (yes,
bad
choice for the name) to this:

private static bool Try(out string Hello)
{
bool ret;
string a1, a2, a3;

try
{
for (int i = 0; i < 3; i++)
{
a1 = "1";
a2 = i.ToString() + a1;
a3 = "HELLO";
}
ret = true;
}
catch (Exception)
{
ret = true;
a3 = "sa";
}

Hello = a3;

return ret ==true;
}

a3 is still unassigned to the compiler. IMHO both ret and a3 are assigned
definetly (it has catch all), and in any case, as they both have the same

No, because the compiler can't be sure that the code inside the for
loop will be executed so there is a chance that you might exit the try
block without assigning a3. Suppose your for loop used a variable as
the upper limit instead of a number:

for (int i = 0; i < SomeVar; i++)

Since the compiler does not know the value of SomeVar at compile time,
it can't be sure that the for loop will be entered so that a3 can be
assigned.

I think this is why it is complaining, because there is a path through
the code in which it is possible for a3 to remain unassigned when it
reaches the line where you are using its value to assign to the Hello
variable.

Jan 29 '07 #7
Technically, the compiler possibly could - but it would not meet the
very specific rules (on definite assignment) in the C# specification,
so you'd probably need to change that first...

This unrolling would only work for very simple examples. Personally, I
like that it is consistent - i.e. the rules are the same for both
complex and simple scenarios. I am human, and I am fallible: I can
only remember so much. If the current compiler behaviour reduces the
number of special cases I need to worry about, then I say "good for
it".

Marc
Jan 29 '07 #8
Jon,

I don't see any rationale for the compiler not checking the loop. As it
checks the condition to resolve it as bool it could check if the body is
reacheable. The c++ compiler compiles it without complaining.

As your for (int i = 10; i < 3; i++), shouldn't the compiler give a warning
"Unreachabl e code detected". i has local scope so it cannot be changed
anyway outside it's scope.

LT
"Jon Skeet [C# MVP]" <sk***@pobox.co mha scritto nel messaggio
news:MP******** *************** *@msnews.micros oft.com...
Laura T. <LT@NOWHERE.COM wrote:

<snip>
>a3 is still unassigned to the compiler. IMHO both ret and a3 are assigned
definetly (it has catch all), and in any case, as they both have the same
flow, I'd at least expect that it would complain on both cases. Ok, there
is
a ret=true, but it does not get executed if i.tostring() would throw. If
I
comment it out, then compiler says that both ret and a3 are unassigned.
If I
add a3="HELLO"; after ret=true; I get no errors.

ret is definitely assigned at the end of the try block - a3 isn't. You
see, the compiler doesn't see the difference between:

for (int i = 0; i < 3; i++)
{
a1 = "1";
a2 = i.ToString() + a1;
a3 = "HELLO";
}

and

for (int i = 10; i < 3; i++)
{
a1 = "1";
a2 = i.ToString() + a1;
a3 = "HELLO";
}

Note how it will never enter the main part of the block in the second
example. The compiler doesn't check that the condition of the for loop
is always true for the first iteration, and thus make a1-a3 definitely
assigned because of it.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Jan 29 '07 #9
IMHO it is not so trivial and uncommone case. It can lead to some good
optimizations.
A quite uncommon case is when the loop is changed to for (int i = 10; i < 3;
i++) so it's clearly not excutable and the expression has no side effects
since its local scope, the compiler/JIT still generate code for it.

for (int i = 10; i < 3; i++)
00000066 inc dword ptr [ebp-28h]
00000069 cmp dword ptr [ebp-28h],3
0000006d jl 0000003F

For example the C++ compiler for example here skips all the code, because it
is unreacheable (no warning though).
Ok, it's not the best example but just a curiosity.

"Marc Gravell" <ma**********@g mail.comha scritto nel messaggio
news:uB******** ******@TK2MSFTN GP03.phx.gbl...
Technically, the compiler possibly could - but it would not meet the very
specific rules (on definite assignment) in the C# specification, so you'd
probably need to change that first...

This unrolling would only work for very simple examples. Personally, I
like that it is consistent - i.e. the rules are the same for both complex
and simple scenarios. I am human, and I am fallible: I can only remember
so much. If the current compiler behaviour reduces the number of special
cases I need to worry about, then I say "good for it".

Marc

Jan 29 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
3947
by: Mike P | last post by:
I keep getting the error 'Use of unassigned local variable' in my code, which I have used before and it works fine : SqlTransaction Trans1, Trans2; SqlConnection objConnectionDeactivateInvisilinkLNX, objConnectionDeactivateInvisilinkSQLSRVXwireless; SqlCommand objCommandDeactivateInvisilinkLNX, objCommandDeactivateInvisilinkSQLSRVXwireless;
2
1511
by: Eric Sabine | last post by:
I just need to understand this bit. In some code, I had the following give me an error at build time XmlDocument xmlDoc; xmlDoc.LoadXml(xmlString); The error was "unassigned use of local variable" on the second line at xmlDoc I ammended the first line to include " = null" and it compiled fine. Could
5
1337
by: Mike P | last post by:
I am instantiating a class in a switch statement as there are a number of different overloads depending upon the data entered by the user. The problem I have is that after instantiating my class, when I try to call methods in the class later on in my code using the same object I cannot, I get the error 'use of unassigned local variable'. How do I get around this as I need some sort of switch/if statement to instantiate my class?
12
1980
by: Rene | last post by:
I understand that if I don't assign a *local* variable before I use it, the compiler will generate a "Use of unassigned local variable" error. What I don't get is why doesn't the compiler just implicitly assign a default value to my unassigned variable? At this point you are getting ready to reply to me and tell me that this is just a way for the compiler to protect me from introducing a possible bug by preventing me from forgetting to...
3
6468
by: John Smith | last post by:
In the following (pseudo)code, why is it that C# returns an "unassigned local variable" error for nVar? It seems I have to declare the variable outside foo() for the error to dissapear. void foo() { int nVar = 0; SqlDataReader rdr = objCmd.ExecuteReader();
29
2232
by: Joseph Geretz | last post by:
Use of unassigned local variable 'fs' Please see where I've indicated where the compiler is flagging this error in the method below. fs is initialized in the first line in the try block, so why is it flagged as unassigned in the finally block? Thanks for your help! - Joe Geretz -
9
6179
by: tshad | last post by:
I am getting an error: Use of unassigned local variable 'postDateRow' But it is assigned. Here is the code: int payDateRow; int postDateRow;
8
11141
by: Dom | last post by:
This is a little tricky, but I think the error I'm getting isn't valid. The compiler just doesn't know my logic. MyObject o; switch (IntVariable) { case 1: o = new MyObject() break;
0
7981
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
7894
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8392
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8262
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6711
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
3938
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2410
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1500
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
1245
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.