Home All Groups Group Topic Archive Search About

Declaring Variables Within a If Steatement

Author
11 Jan 2006 9:20 PM
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.

Author
11 Jan 2006 10:00 PM
Herfried K. Wagner [MVP]
<jhigh***@gmail.com> schrieb:
Show quoteHide quote
> 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.

--
M S   Herfried K. Wagner
M V P  <URL:http://dotnet.mvps.org/>
V B   <URL:http://classicvb.org/petition/>
Author
11 Jan 2006 10:57 PM
Armin Zingler
<jhigh***@gmail.com> schrieb
Show quoteHide quote
> 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
Author
12 Jan 2006 1:02 PM
AMercer
> 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."
Author
12 Jan 2006 5:12 PM
_AnonCoward
<jhigh***@gmail.com> wrote in message
Show quoteHide quote
news:1137014442.878387.29080@g14g2000cwa.googlegroups.com...
: 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
--
--
----------------------------------------------------------
*             ^~^                   ^~^                  *
*          _ {~ ~}                 {~ ~} _               *
*         /_``>*<                   >*<''_\              *
*        (\--_)++)                 (++(_--/)             *
----------------------------------------------------------
There are no advanced students in Aikido - there are only
competent beginners. There are no advanced techniques -
only the correct application of basic principles.