Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Re: Re: for loop localisation bug?

by Corion (Pope)
on Dec 29, 2003 at 16:44 UTC ( #317466=note: print w/ replies, xml ) Need Help??


in reply to Re: for loop localisation bug?
in thread for loop localisation bug?

In both, C and Pascal, the value of the loop counter variable after leaving the loop (however) is undefined. This is to allow the compiler to optimize its loop construct, as some compilers only have one internal loop construct and convert the syntactic candy of for, while and their ilk to it - or at least I believe that's why it was defined as undefined/implementation specific.

perl -MHTTP::Daemon -MHTTP::Response -MLWP::Simple -e ' ; # The $d = new HTTP::Daemon and fork and getprint $d->url and exit;#spider ($c = $d->accept())->get_request(); $c->send_response( new #in the HTTP::Response(200,$_,$_,qq(Just another Perl hacker\n))); ' # web


Comment on Re: Re: for loop localisation bug?
Download Code
Re: Re: Re: for loop localisation bug?
by BrowserUk (Pope) on Dec 29, 2003 at 18:06 UTC

    I beg to differ, at least as far as C is concerned.

    #include <stdio.h> void main() { int n; for( n=0; n<10; n++ ) { printf( "%d\n", n ); if( n == 5 ) break; } printf( "Residual value: %d\n", n ); } __END__ P:\test>bcc32 test.c Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland test.c: Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland P:\test>test 0 1 2 3 4 5 Residual value: 5

    And even in languages that allow the loop variable to be declared within the for loop initialiser statement, it's scope is not that of the for loop body, but that of the enclosing block.

    From p.38 of "Programming in C++ by Stephen C. Dewhurst & Kathy T. Stark"

    Declarations are statements and can appear any place a statement can within a block. This flexibility allows names to be declared and initialised at the point of their first use. For example, the first clause in a for loop control is a statement so a loop index can be declared there.
    for( int i = 0; i < limit; i++ ) { // etc. } return i;

    The scope of the name extends from its point of declaration to the end of the enclosing block. Notice that in this example, i is still available after the loop terminates. It goes out of scope at the end of the block that contains the for statement.

    I don't have a Pascal reference handy, but I seem to recall (from a very long time ago) that it's for loop acted similarly.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    Hooray!

      I have absolutely no evidence here, but all your example proves is that specific implementation retains the value in the loop iterator. I don't have the C spec handy so I have nothing to prove that Corion is right, but I too seem to recall something along those lines, that the loop iterator is undefined after the loop and so it's best practice not to rely on it, regardless that it's defined for probably 95% of the compilers.

        Sorry, but I think you are wrong on this. Checking both K&R (the original version from circa. 1978) and the ANSI C specification, particularly Scopes of identifiers and Iteration statements, I can find nothing to support your position.

        Identifiers in C are block scoped, the iterator variable in a for loop must be declared prior to the for loop and there is nothing special about it. It retains the last value set until that value is changed, regardless of whether the statement that changed it is a simple assignment, inside or outside of a loop body, or even as one of the three statements that make up the for loop control statements. It remains in scope and defined until the block at which it was defined is exited.

        It is never undefined, and any such statement of 'best practice' is simply ignoring both the design specification and the realities of implementations. It buys you nothing.


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "Think for yourself!" - Abigail
        Hooray!

      After some searching, I found this link for Pascal, which tells what I know about Pascal, that the value is undefined after leaving the loop. I think that Turbo Pascal and Borland Pascal had the value of the upper bound of the loop at the end of the loop, but confusion started once they implemented optimizations in BP7 and Delphi.

      For C, I browsed the standard a bit, but didn't stumble on anything going in either direction, so I guess the behaviour is neither implementation defined nor undefined but merely unspecified (some FAQ goes to some lengths to explain the differences between these three regarding the ANSI C standard...). I guess that one will find ugly differences soon enough if one uses enough different compilers and not only gcc...

      The same pages as for the Pascal link give some remarks about C loops, but also no hint as to what the value of the loop iterator is after leaving the loop.

      perl -MHTTP::Daemon -MHTTP::Response -MLWP::Simple -e ' ; # The $d = new HTTP::Daemon and fork and getprint $d->url and exit;#spider ($c = $d->accept())->get_request(); $c->send_response( new #in the HTTP::Response(200,$_,$_,qq(Just another Perl hacker\n))); ' # web

        I said my Pascal was a long time ago:) I dug up a little info on the last Pascal compiler I used -- in a museum!

        For C, I think the info I dug up and posted here is reasonably definitive. With deference to MADuran's info on C99 which I've never encountered, there is no definitive statement on the state of a C for loop variable after a for loop, simply because there is nothing special about a for loop variable in C.

        • It is simply a variable that has a scope defined by the block in which it is declared.
        • It must have been declared before it can be used in the for loop.
        • Any modifications made to it, either by the control statements or within the for loop body, persist after the for loop terminates, and until it goes out of scope.
        • It remains in scope, until the block it was defined in, ends.

        One all. Now lets get back to perl:)


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "Think for yourself!" - Abigail
        Hooray!

      Please don't use void main. It's broken, just like double main or union {int x; float y; } **main.

      The C standard says: main() must be declared as int main(void) or int main(int, char **) or equivalent (or in some implementation-defined manner, which is inherently unportable). See also http://users.aber.ac.uk/auj/voidmain.shtml.

        What can I say? It served its purpose. See you at SeaMonks.com for the follow-up:)


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "Think for yourself!" - Abigail
        Hooray!

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://317466]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (11)
As of 2014-07-11 00:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (217 votes), past polls