Declaring Variables Within a If Steatement

  • Thread starter Thread starter jhightow
  • Start date Start date
J

jhightow

The following code :

For i as system.Int32 = 0 to 4
If i < 2 Then
Dim s as System.String
s &= i.ToString
Console.WriteLine(s)
End If
Next

For i as system.Int32 = 0 to 4
If i < 3 Then
Dim n as System.Int32
n += i
Console.WriteLine(n)
End If
Next

Returns the following results :
0
01
0
1
3

Could someone explain why s is not set to nothing and n is not set 0.
At start of each loop.
 
For i as system.Int32 = 0 to 4
If i < 2 Then
Dim s as System.String
s &= i.ToString
Console.WriteLine(s)
End If
Next

For i as system.Int32 = 0 to 4
If i < 3 Then
Dim n as System.Int32
n += i
Console.WriteLine(n)
End If
Next

Returns the following results :
0
01
0
1
3

Could someone explain why s is not set to nothing and n is not set 0.
At start of each loop.


The variable's scope is limited to the 'If' block, but is lifetime is
limited by the "lifetime" of the method. Actually 'n' is a local variable
on procedure level, but the compiler only allows access to it inside the
'If' block.
 
The following code :

For i as system.Int32 = 0 to 4
If i < 2 Then
Dim s as System.String
s &= i.ToString
Console.WriteLine(s)
End If
Next

For i as system.Int32 = 0 to 4
If i < 3 Then
Dim n as System.Int32
n += i
Console.WriteLine(n)
End If
Next

Returns the following results :
0
01
0
1
3

Could someone explain why s is not set to nothing and n is not set
0. At start of each loop.


It's still a local variable that lives as long as the function lives. All
local variables are put on the same stack frame. However, the scope of the
variable is limited to the If-block.


Armin
 
Could someone explain why s is not set to nothing and n is not set 0.
At start of each loop.

Good question, but it is by design, and it is different from similar C
constructs. If you explicitly code an initializer (nothing for s, 0 for n),
it will behave as you wish. In your case, the issue is default initializers.
Below is from .net online help - note the last sentence.

"Variable initializers on locals are equivalent to assignment statements
placed at the textual location of the declaration. Thus, if execution
branches over the local declaration, the variable initializer will not be
executed. If the local declaration is executed more than once, the variable
initializer will be executed an equal number of times. It is important to
note that locals are only initialized to their type's default value once,
upon entry into the method."
 
: The following code :
:
: For i as system.Int32 = 0 to 4
: If i < 2 Then
: Dim s as System.String
: s &= i.ToString
: Console.WriteLine(s)
: End If
: Next
:
: For i as system.Int32 = 0 to 4
: If i < 3 Then
: Dim n as System.Int32
: n += i
: Console.WriteLine(n)
: End If
: Next
:
: Returns the following results :
: 0
: 01
: 0
: 1
: 3
:
: Could someone explain why s is not set to nothing and n is not set 0.
: At start of each loop.


As others have pointed out, the varibles exist at the procedural level but
the scope is limited to the If Then / End If blocks. For example, the
following is not allowed:


'===============================================
For i as system.Int32 = 0 to 4
If i < 2 Then
Dim s as System.String
s &= i.ToString
Console.WriteLine(s)
End If

'out of scope!
Console.WriteLine(s)

Next
'===============================================


This will generate the error "Name 's' is not declared.'. This is a little
misleading because of course it's been declared, it just isn't visible at
the point where you are trying to get it. (Imo, a better error message would
be "Name 's' is not declared or is not in scope" or something to that
effect. But whatever).


Note that vb.net 2.0 (compiler version 8.0.50727.42) will not compile the
original code example. If you leave the following line unchanged:


Dim s as System.String


The compiler generates the following warning


warning BC42104: Variable 's' is used before it has been
assigned a value. A null reference exception could result at
runtime.

s &= i.ToString
~


This is much more like how C# works. To get around this, you have to disable
warnings when compiling


vbc /nowarn


Or just disable this specific warning


vbc /nowarn:42104


Alternatively, you could initialize the variable when you declare it:


Dim s as System.String = ""


In this case however, the output changes:


0
1
0
1
3


In this case, the String object "s" is reinitialized in each iteration
through the loop. You can see this more clearly in this example:


'===============================================
For i as system.Int32 = 0 to 4
If i < 2 Then
Dim s as System.String = "x"
Console.WriteLine(s)
s &= i.ToString
Console.WriteLine(s)
End If
Next
'===============================================


The output from this is:

x
x0
x
x1


Note that the compiler doesn't care that you left the value type 'n'
uninitialized when you declared it in the second loop. If I recall
correctly, value types can't be "Nothing" but will always be given a value
when declared (int32 defaults to 0 if not specified). Therefore, not
declaring the initial value for 'n' does not generate the warning.


However, change that line to read


Dim n as System.Int32 = 0


and you'll get a different result when you run the code.


0 'was 0
1 'was 1
2 'was 3


In this case, the variable n is reset to '0' each time the loop runs.


Interesting stuff, eh?


Ralf
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top