While (and For) loops with strings



  • Say I have the follwoing code:

    <FONT size=2>

    </FONT><FONT color=#0000ff size=2>Sub</FONT><FONT size=2> Main()

    </FONT><FONT color=#0000ff size=2>Dim</FONT><FONT size=2> intI </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>Integer</FONT><FONT size=2> = 0
    </FONT><FONT color=#0000ff size=2>Dim</FONT><FONT size=2> intJ </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>Integer</FONT><FONT size=2> = 0

    </FONT><FONT color=#0000ff size=2>While</FONT><FONT size=2> intI < 10
    </FONT><FONT color=#0000ff size=2>
    Dim</FONT><FONT size=2> strTest </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>String
    </FONT><FONT color=#0000ff size=2>If</FONT><FONT size=2> strTest </FONT><FONT color=#0000ff size=2>Is</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>Nothing</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>Then
    </FONT><FONT size=2>intJ += 1
    strTest = "Been here"
    </FONT><FONT color=#0000ff size=2>End</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>If
    </FONT><FONT size=2>intI += 1
    </FONT><FONT color=#0000ff size=2>
    End</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>While

    </FONT><FONT size=2>

    Console.WriteLine(intI & " : " & intJ)
    </FONT><FONT color=#0000ff size=2>End</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>Sub</FONT>

    <FONT color=#0000ff size=2><FONT color=#000000>What would you expect it to return?</FONT></FONT>



  • Ummm... 10:10 ....




  • Too bad it returns 10 : 1

    Yes, a string DIMmed in a while loop seems to be static, and so has a value already if you re-enter the while loop. The value is not removed at the next DIMming.

    Didn't someone once post that Dim strString as String = Nothing was bad practice? I think this proves otherwise :P

    Drak



  • Odd. I would have expected that in each iteration in the loop the
    string would have been reinitialized to nothing, or an empty, due to
    scoping rules. Hm, I guess scope doesn't mean the same thing in VB as
    it does in C++. Question is, can you access the string after the while
    loop?



  • Hmm,



    Actually, after breaking out VB.NET (a rare occurance...) The program
    works as expected if strTest is dimmed as "Dim strTest as String =
    Nothing", but doesn't work as expected when strTest is not initialized
    in the Dim statement. It was my understanding that Dim automatically
    initialized variables at the point they were dimmed.






  • Apparently VB doesn't do proper scoping, or else treats things defined
    in scope as static. Either is weird behaviour. Does it treat function
    variables as static by default as well?



  • Uhm, function variables are always initialized.

    Optional parameters have to be supplied with a default value, so I think you cannot have uninitialized function variables.

    Drak

    ps. You cannot access the string from outside of the while loop. It wouldn't compile [;)]

     



  • An aside:



    This simple C program behaves as the above VB program:



    int main()

    {

        int intI = 0;

        int intJ = 0;



        while(intI < 10)

        {

            int iTst;

            if(iTst != 1)

                intJ+=1;

            iTst = 1;

            intI++;

        }



        printf("%i:%i", intI, intJ);

        return 0;

    }



    Interestingly, This (less simple, but still simple) C++ program does not:



    struct CTest

    {

        CTest(int i = 0)

        {

            m_val = i;

            printf("Construct\n");

        }



        ~CTest()

        {

            printf("Destruct\n");

        }



        operator int ()

        {

            return m_val;

        }



        int m_val;

    };



    int main()

    {

        int intI = 0;

        int intJ = 0;



        while(intI < 10)

        {

            CTest iTst;

            if(iTst != 1)

                intJ+=1;

            iTst.m_val = 1;

            intI++;

        }



        printf("%i:%i", intI, intJ);

        return 0;

    }



    If you run it, you'll see a series of 10 construct/destruct pairs, then the expected output 10:10.



    The reason? While both are store on the stack, the CTest object's
    constructor gets called at the beginning of the loop, and the
    destructor at the end of the loop. If you remove the destructor, it
    acts as the VB Program. Of course, the output of uninitialized data is
    not defined... This is an artifact of the compiler's stack, the
    variable just simple winds up at the same location on the stack every
    time. [:D]



  • Just a question. Why are u using strTest like an object?



  • oh, I see....fucking VB.NET



  • The MSDN library documentation on variable lifetime in VB.NET explains all this.

    To quote:

    Variables declared within a block inside a procedure are initialized to their default values on entry to the procedure. These initializations take effect whether or not the block is ever executed.


  • [quote user="zinglons_ale"]The MSDN library documentation on variable lifetime in VB.NET explains all this.
    To quote:

    Variables declared within a block inside a procedure are initialized to their default values on entry to the procedure. These initializations take effect whether or not the block is ever executed.

    [/quote]

    It's fairly simple, scoping rules are a PITA. So Microsoft in their infinite wisdom made sure that while the SCOPE of a variable is limited to it's current block - {} in C++ terms - the instantiation can only happen once. I am pretty sure there is a flag in the visualstudio that will yell at you for trying to redim a dim'd variable - a warning at the very least. This is just so you don't get those silly errors where your data never does what it is supposed to. They want you to do a dim x as integer = 0 to reset. Actually, i wonder if throwing the = 0 at the end will fix the loop you have above, OP? VB.Net does have a lot of perks, such as shallow learning curve and enough power to handle most things, but stuff like this can drive a programmer insane (i.e. you expect the variable to get cleared every time through the loop)

    dim myString as String = nothing 'should fix it


Log in to reply