Microsoft 开发人员网络 > 论坛主页 > Visual Basic Language > Problem in FOR loop ... Is it a BUG ?!!
提出问题提出问题
 

常规讨论Problem in FOR loop ... Is it a BUG ?!!

  • 2008年11月2日 23:58The_knight5000 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     包含代码



    Hello all ,

    I discovered that error by chance when I was working on Collections. But I found it in FOR loop in VB.Net.

    Have a Look :
    Sub Main()  
           
            Dim Y As Integer = 10  
            For x As Integer = 0 To Y  
                Console.WriteLine(x.ToString())  
                Y = Y - 1  
            Next  
            Console.ReadLine()  
    End Sub 
     
     
    'and the result was 
    10 
     
     
    'and that is not logically correct !! 
     
    'the Correct result should be : 
     
    'as Y decreased every step. 

    In other words : why FOR loop limit is not updated every step!!!! ? Is it a Bug or What ?!


    thanks in advance !!





全部回复

  • 2008年11月3日 0:02JohnWein 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    By design.  Try increasing the lower limit within the loop.
  • 2008年11月3日 0:16David Anton 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    The ending condition of VB for loops is always evaluated just once before the looping begins.  This is different from the 'C-style' languages, such as C#, C++, and Java, where the ending condition is constantly re-evaluated.


    Convert between VB, C#, C++, and Java (http://www.tangiblesoftwaresolutions.com)
  • 2008年11月3日 0:25The_knight5000 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
     Hello ,

    @JohnWein: I didn't geet it , what do u mean !?

    @David Anton : I got it recently , and i think it is not wise logic , Is it ?! why did they make it like that ?!
  • 2008年11月3日 0:37David Anton 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    I'm not sure, but it's consistent.  The VB 'For' loop is very static - there is nothing executed in the actual 'For' statement after the initial evaluation.  In C#/C++/Java, the initializer is evaluated just once, but the other two statements (usually used for the ending condition and loop incrementer, although you can put any statements there) are executed on every iteration. 
    Convert between VB, C#, C++, and Java (http://www.tangiblesoftwaresolutions.com)
  • 2008年11月3日 1:26The_knight5000 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    mmm , I'm not talking about "the actual 'For' statement" ,it was in the code block !! and actually it raises OutOfRange exceptions when u use it like that with collections , or some logic errors just like above snippet !!

    MCP (Developing Web Applications ) MCP (Developing Windows Applications ) MCP (Designing and Implementing Databases with Microsoft® SQL Server™ 2000)
  • 2008年11月3日 6:36John Anthony Oliver 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     包含代码
    Hi The_knight5000,

    As is often said in these forums, VB.Net is NOT C is NOT C# and is NOT C++



    Expect different things to happen in VB.Net



    However you do raise an interesting point.

    You can only affect the START and END values of a FOR NEXT loop in VB.Net
     from outside the loop it seems as I have just tried it.


    Dim sb As New System.Text.StringBuilder

    Dim LoopStart As Integer = 0

    Dim
    LoopEnd As Integer = 10

    For
    x As Integer = LoopStart To LoopEnd

    'You can NOT change LoopStart or LoopEnd within
    ' a FOR NEXT loop within Vb.Net as I have just tried it.
    sb.Append(x.ToString & " ")
    Next x

    MessageBox.Show(sb.ToString)




    Then try this.>>

    Option Strict On
    Public
    Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Dim sb As New System.Text.StringBuilder
    Dim LoopStart As Integer = 0
    Dim LoopEnd As Integer = 10

    Do
      For x As Integer = LoopStart To LoopEnd
        'You can NOT change LoopStart or LoopEnd within
        ' a FOR NEXT loop within Vb.Net
        sb.Append(x.ToString & " ")
      Next x
    LoopEnd = LoopEnd - 1
    Loop Until LoopStart = LoopEnd

    MessageBox.Show(sb.ToString)
    End Sub
    End
    Class




    Regards,

    John


    For links to VB.Net tutorials see here.>> http://social.msdn.microsoft.com/Forums/en-US/vblanguage/thread/29f2179b-997b-4115-a96d-a0834853b835
  • 2008年11月3日 17:23SJWhiteley版主用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    The_knight5000 said:

    mmm , I'm not talking about "the actual 'For' statement" ,it was in the code block !! and actually it raises OutOfRange exceptions when u use it like that with collections , or some logic errors just like above snippet !!


    MCP (Developing Web Applications ) MCP (Developing Windows Applications ) MCP (Designing and Implementing Databases with Microsoft® SQL Server™ 2000)


    Iterating through a collection isn't the same as a for/next loop.

    Your 'correct' loop probably arises from your familiarity with C style languages (which VB programmers may consider to be 'incorrect'). If you can answer this question "Which is the correct side of the road to drive a car?" you have answered your above question :)

    Stephen J Whiteley
  • 2008年11月3日 18:28The_knight5000 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     包含代码
    Good Evening,

    Hey all , I'm not trying to avoid that or asking for alternative way to pass this situation in my code , I just asking why is For loop in VB.Net like that ? , and I'm wondering why do MS Developers Consist on that way also in the newest version ?!!


    @John Anthony Oliver: really thanks for ur interest and I know I can't change the limits of the loop inside the loop block :s , and I still asking why ?!
    btw , ur snippet does not solve the problem , It just involve code into nested loops !


    SJWhiteley
    :

    SJWhiteley said:

    Iterating through a collection isn't the same as a for/next loop.

    Your 'correct' loop probably arises from your familiarity with C style languages (which VB programmers may consider to be 'incorrect'). If you can answer this question "Which is the correct side of the road to drive a car?" you have answered your above question :)

    Stephen J Whiteley

    Ok man , It may be different  , But we don't care about what we are looping through , I talking here about the FOR Statement itself.

    I think loops in Vb or C# or whatever the tool should use the same logic , and Actually i think this VB logic  in implementing for statement is not right .

    when I'm talking about collections , I meant some thing like that :



            Dim arr As New ArrayList(4) 
            arr.AddRange(New Integer() {1, 2, 3, 4, 5}) 
            For i As Integer = 0 To arr.Count - 1 
                Console.WriteLine(arr(i)) 
                arr.RemoveAt(arr.Count - 1) 
            Next 

    it should update the end limit (arr.count) every time it loops , but this does not happen , it catch the arr.Count at the first time only , and it will be not updated ..... why ?this is my questing and i think that is incorrect logic !!!!!!!


    thanks









    MHamdy
    MCP (Developing Web Applications )
    MCP (Developing Windows Applications )
    MCP (Designing and Implementing Databases with Microsoft® SQL Server™ 2000)
  • 2008年11月3日 20:35SJWhiteley版主用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    VB has always performed loops like that. This implies a consistency. And honestly, consistency is a lot more important than correctness (whatever that may be perceived to be), in general.

    As for your example, it demonstrates the consistency: once the loop is set, it is set. it does update the count, but in your example, as we have said, the For/Next loop does not re-evaluate its bounds once you have established those bounds.

    I suspect, for the foreseeable future, this is how VB loops will always execute. Remember, you have a choice of languages; although they operate on the same framework there are quirks which differentiate them.

    Really, asking for a change like this (breaking millions of applications) is not going to happen - until they remove the useless semicolons from C ;)

    Seriously, though, this is quite a useful feature - it means you can perform a time consuming/complex operation to calculate your loop bounds (for example, establishing a record count in a dataset), without it having to be recalculated through each iteration.

    For i as integer = ComplexOperationLower to ComplexOperationUpper
        ' Do Some More Stuff without reevaluating the ComplexOperationUpper or ComplexOperationLower
    next


    Or, if that doesn't satisfy you: it is what it is; Like it or lump it; If you can't stand the heat; horses for courses, etc. Personally, I use VB because I can't stand the quirks and inconsistencies of C.

    Stephen J Whiteley
  • 2008年11月3日 21:47dbasnett 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     包含代码
    sjw is correct, and the point about limit being a complicated formula is well taken.  if you need it both ways

            Dim aY As Integer = 10 
            Dim ax As Integer 
            For ax = 1 To aY 'tell For I want to do something 10 times 
                Debug.WriteLine(ax.ToString()) 
                aY -= 1
                If aY = 5 Then Exit For 'oh, but not really, i meant 5 times 
            Next 
            'or 
            Dim aZ As Integer = 5 
            ax = 1 : aY = 10 
            Do While aY <> 0 AndAlso aY <> aZ 
                Debug.WriteLine(ax.ToString) 
                ax += 1 
                aY -= 1 
            Loop 
     

  • 2008年11月4日 1:10John Anthony Oliver 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    SJWhiteley said:

    Or, if that doesn't satisfy you: it is what it is; Like it or lump it; If you can't stand the heat; horses for courses, etc. Personally, I use VB because I can't stand the quirks and inconsistencies of C.


    Stephen J Whiteley



    Hi again The_knight5000,

    Despite what has been previously said, and you having 3 MCP qualifications, I have to agree with Stephen J Whiteley and anyone else who might write; "Like it or lump it"

    You can not honestly expect consistencies between ALL programming languages, surely?

    If Visual Basic has always been this way since Visual Basic version 1.00 , then why should Microsoft change things in Visual Basic? Besides the BASIC programming language was invented in 1964 according to http://en.wikipedia.org/wiki/Basic_programming_language so that makes it 44 years old ( 1 year older than me!! ).

    C was created later in 1972 according to http://en.wikipedia.org/wiki/C_programming_language some 8 years later.

    What I am really getting that though is,

    if FOR NEXT loops in BASIC have always been like this then why should anyone change the programming language specification and introduce a potential bug - problem?


    Regards,

    John


    For links to VB.Net tutorials see here.>> http://social.msdn.microsoft.com/Forums/en-US/vblanguage/thread/29f2179b-997b-4115-a96d-a0834853b835
  • 2008年11月5日 1:34The_knight5000 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    Hello All


    SJWhiteley said:

    Or, if that doesn't satisfy you: it is what it is; Like it or lump it

    John Anthony Oliver said:

    if FOR NEXT loops in BASIC have always been like this then why should anyone change the programming language specification and introduce a potential bug - problem?


    Actually I don't know what to say , that is really disappointing !!

    Java , PHP , C , C# ... Implements Dynamic for Loop (as I can call) , and it is already stable and consistent !!
    and you just should know this Static For loop in VB has a logic error !!

    this is the reply of Jonathan Aneja on My Bug Report:
    Hi there,

    This behavior is by design, as documented in the help topics. VB has several different looping constructs that provide a lot of flexibility here - in this case you could use a "Do While" or "Loop Until" if you want the ability to dynamically change the upper bound.

    I'm going to resolve this bug as "by design" for now, but if you have any questions feel free to contact me directly .

    Thanks,

    Jonathan Aneja
    Program Manager, VB Team

    thanks all , I just wanted to report about this !

    regards,

    MHamdy

    MHamdy
    MCP (Developing Web Applications )
    MCP (Developing Windows Applications )
    MCP (Designing and Implementing Databases with Microsoft® SQL Server™ 2000)
  • 2008年11月5日 13:19dbasnett 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    "Actually I don't know what to say , that is really disappointing !!

    Java , PHP , C , C# ... Implements Dynamic for Loop (as I can call) , and it is already stable and consistent !!
    and you just should know this Static For loop in VB has a logic error !!"

    it is well documented (imagine reading the instructions), but so few do.  if you want the code to do what java, c, et al do then write in those languages

    imho - for's are used to do something a specific amount of times.  what if the loop was hundred's of lines of code?  imagine debugging that.  the problem is really in your original construct, which probably should have been a do loop.

    i got on my soap box once about 12:00 AM PM NOON MIDNIGHT, and even though i was correct, i lost. so my advice is do whatever you need to do to get over your disappointment, and move along.

    "Give us grace to accept with serenity the things that cannot be changed, courage to change the things that should be changed, and the wisdom to distinguish the one from the other."
  • 2008年11月5日 13:41Dig-Boy 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    I think everyone has provided a broad, well-rounded explanation and discussion of the topic and there is little more to be squeezed from it.  From my perspective you can be clumped in with the masses who find fault with VB (or down-right hate it) because it does not do the things that their favorite language(s) do.  If you post this on the C# forum you might find an equal chorus willing to agree with you about this.
  • 2008年11月5日 14:22John Anthony Oliver 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     包含代码
    dbasnett said:

    The problem is really in your original construct, which probably should have been a do loop.


    Hi ALL,

    I agree with this too.

    You can achieve the same as the OP The_knight5000 was expecting like this.>>

    Option Strict On

    Public
    Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Dim sb As New System.Text.StringBuilder
    Dim Y As Integer = 10
    Dim x2 As Integer = 0

    'The result you are after with a DO LOOP.>>
    Do
    sb.Append(x2.ToString & Environment.NewLine)
    x2 = x2 + 1
    Y = Y - 1
    Loop Until Y < 5

    MessageBox.Show(sb.ToString)


    sb = New System.Text.StringBuilder
    Dim x3 As Integer = 0
    Y = 10

    'The result you are after with a WHILE LOOP.>>
    While Y > 4
    sb.Append(x3.ToString & Environment.NewLine)
    x3 = x3 + 1
    Y = Y - 1
    End While

    MessageBox.Show(sb.ToString)

    End Sub
    End
    Class


    For links to VB.Net tutorials see here.>> http://social.msdn.microsoft.com/Forums/en-US/vblanguage/thread/29f2179b-997b-4115-a96d-a0834853b835
  • 2008年11月5日 14:34dbasnett 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    i already posted a do loop example, in a lot less space ;)
  • 2008年11月5日 16:31SJWhiteley版主用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    Thankfully, these kind of 'discussions' pop up a lot less than they used to with VB6/C++.

    Historically (and currently?) VBers get very defensive when 'their' language is attacked for being wrong, and C programmers tend to see themselves as better for using an obviously superior language.

    Unfortunately, it'll probably always be this way: VB has a lot of baggage associated with it. Some are just quirks, some are actually better and more logical methodologies compared to C, and some should just go away (but won't).

    With VB and C# being so comparable, the differences generally fall down to the quirks and taste. Additionally, as has been posted, there is more than one way to do a specific task.


    Stephen J Whiteley