Xtreme Visual Basic Talk

Xtreme Visual Basic Talk (http://www.xtremevbtalk.com/)
-   .NET Communications (http://www.xtremevbtalk.com/-net-communications/)
-   -   I thought that Double and Integer are initilised to Zero by Default (http://www.xtremevbtalk.com/-net-communications/327416-double-integer-initilised-zero-default.html)

naton 12-03-2014 02:03 AM

I thought that Double and Integer are initilised to Zero by Default
 
Hi there,
I'm using Visual Studio 2005, and my VB code is misbehaving. I initially thought it was a bug in Visual Studio, but updating it with Service Pack 1 did not solve this issue.

Basically, in the code below, the variable "average" is not reset to zero but retains its value from the previous loop. It is behaving as a public variable.

Am I doing something wrong?

Code:

Class Car
  private power as Double
  private shared rnd as Random = new Random (1234)

  Public Sub New(Byval maxPower as Double)
      power = rnd * maxPower
  End Sub

  Public Function MyPower() as double
      Return power
  End Function
End Class

Class FleetOfCar
  private cars() as Car
 
  Public Sub New(Byval numberOfCars as Integer, Byval maxPower as Double)
      ReDim cars(numberOfCars - 1)

      For i as Integer = 0 to numberOfCars - 1
        cars(i) = New Car(maxPower)
      next
  End Sub

  ' Here is the issue. the variable "average" passed to this function retains the value from
  ' the previous loop instead of been reset to zero.

  Public Sub ComputeAverage(Byref average as double, Byval thresholdPower as double)
      For i as Integer = 0 to cars.GetUpperBound(0)
          if cars(i).MyPower > thresholdPower Then average++
      Next

      average = average / cars.Length
  End Sub
End Class

Public Sub Main()
  Dim MyFleetOfCars as FleetOfCars
  Dim maxPower as Double = 200
  Dim numCars as integer = 20

  For i as Integer = 0 to 10
      FleetOfCars = New FleetOfCars(numCars, maxPower)

      Dim average as Double      ' This variable is not reset to zero after each loop
      FleetOfCars.ComputeAverage(average, maPower / 2)
      Console.WriteLine(average)
  Next
End Sub


PlausiblyDamp 12-03-2014 05:51 AM

Within a single method it isn't quite that straight forward unfortunately, C# would have flagged that as an error as average is an uninitialised variable and would have required you to set it to n initial value (e.g. 0). VB.Net is a bit more lax on these things and unfortunately this can lead to very subtle problems.

I would simply initialise the value at the point of declaration and that should sort things out.

Cerian Knight 12-03-2014 06:24 PM

In older VB, the in-line dimensioning of variables simply compiled their creation to the beginning of the sub/function. That seems to be happening here with VB.NET, as well, at least when lacking explicit initialization. However when initialized, it might possibly also use {varname}={initvalue} in the compiled code at the Dim location. The old legacy VB behavior could be demonstrated... a variable could be referenced before it was created (which was just an illusion). I though this loophole was closed in VB.NET.

Sorry, getting off subject. Another option is to use a standard simple y=f(x) function definition (presuming I'm not missing some problem aspect of implementing this in the Class). Thus, moving the 'Dim' line to the beginning of Main and using this instead:
Code:

average = FleetOfCars.ComputeAverage(maPower/2)
Console.WriteLine(average)

or, better yet, implement the standard function definition AND eliminate the 'average' variable altogether:
Code:

Console.WriteLine(FleetOfCars.ComputeAverage(maPower/2))
Note: This was borrowed from the original code, thus preserving the potential mis-spelling of 'maxPower' as 'maPower'.

passel 12-08-2014 02:52 PM

A difference in .Net is that Declaring the variable in the loop does limit the scope of the variable to the loop, and it is initialized to 0 at that time of declaration, and retains whatever value is assigned to it while in scope.
Code:

  Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
    For i As Integer = 0 To 10
      Dim average As Double    ' This variable is initialized to 0, but not reset to zero after each loop
      average += i  'average will accumulate additions
      Debug.Print(average.ToString)
    Next
  End Sub

If you want to initialize to zero each loop, then as PD says, initialize it.
Code:

  Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
    For i As Integer = 0 To 10
      Dim average As Double = 0  ' This variable is initialized to 0 each loop
      average += i  'average will equal i each loop
      Debug.Print(average.ToString)
    Next
  End Sub


naton 12-09-2014 01:54 AM

Hi every one.

At the moment, in order to avoid the issue I have added the following line at the beginning of the sub ComputeAverage():
average = 0

Quote:

Originally Posted by passel (Post 1407505)
A difference in .Net is that Declaring the variable in the loop does limit the scope of the variable to the loop, and it is initialized to 0 at that time of declaration, and retains whatever value is assigned to it while in scope.

This is exactly what I don't understand. MSDN and the reference books I have of VB.NET state that a Double variable is explicitly initialised to 0. In my case it is happening only at the first iteration of the loop (i.e. when i=0).

Correct me if my understanding is wrong. A new loop start every time the variable i is incremented. Having the statement "Dim average as Double" inside the loop means that every time i is incremented a new variable "average" is created which the compiler should explicitly initialise to 0. Thus, for instance, the variable "average" created when i=3 points to a differnet memory location than the variable "average" created when i=4 or i=10. Thus why is the initialisation happening only to the "average" variable created when i=0 but not thereafter?

PlausiblyDamp 12-09-2014 03:23 AM

Variables defined at a class level will be automatically initialised at the point of declaration if you do not provide a value yourself, however variables within a method don't behave the same way.

Within a single method the declaration of the variable within the loop is managing the scope of the variable but not the lifetime of the variable.

Personally I don't like the way VB.Net allows the syntax you initially used anyway as it can cause really subtle bugs.

I would treat the two lines of code at
Code:

Dim average as Double      ' This variable is not reset to zero after each loop
FleetOfCars.ComputeAverage(average, maPower / 2)

as an error because the use of the variable average in the second line is accessing an uninitialized variable.

Cerian Knight 12-09-2014 08:14 AM

Quote:

Originally Posted by PlausiblyDamp (Post 1407511)
Personally I don't like the way VB.Net allows the syntax you initially used anyway as it can cause really subtle bugs.

I agree, thus my previous rambling. The specific issue that concerns me with in-loop variable declaration is that the logic diagram (presuming people still do that, other than me) requires a conditional operator (unless explicit initialization is used) that is not implied by the syntax (or well understood from the documentation).

Not really a big deal... just another one of those 'you don't know till you know' things (that triggered this whole topic).

naton 12-17-2014 02:57 AM

It is a bit late, but still thank you guys.


All times are GMT -6. The time now is 06:47 AM.

Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Search Engine Optimisation provided by DragonByte SEO v2.0.15 (Lite) - vBulletin Mods & Addons Copyright © 2017 DragonByte Technologies Ltd.
All site content is protected by the Digital Millenium Act of 1998. Copyright©2001-2011 MAS Media Inc. and Extreme Visual Basic Forum. All rights reserved.
You may not copy or reproduce any portion of this site without written consent.