473,749 Members | 2,580 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 8428
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
3961
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
1517
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
1993
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
6485
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
2244
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
6192
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
11150
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
8833
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
9389
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...
1
9335
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
1
6801
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6079
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4709
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4881
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
2794
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2218
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.