CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 4 1234 LastLast
Results 1 to 15 of 46
  1. #1
    Join Date
    Jun 2002
    Location
    Germany
    Posts
    1,557

    scope of a variable declared in a for loop

    Hello all code gurus,

    Here is another issue which has bothered me for years.
    One poor soul dared to ask a while ago and the thread turned ugly --- with authors radically defending one development environment over the other and such things.

    So please here just try to stick to the C++ language specification.

    What is the scope of a loop variable?
    I was of the opinion that the scope of i (see code snippet below) must be limited to lines within the loop.

    Some compilers exhibit different behavior regarding this syntax.
    Can anyone verify the proper language specification here?

    #include <iostream>
    using namespace std;

    int main(int argc, char* argv[])
    {

    for(register int i = 0; i < 10; i++)
    {
    cout << i << endl;
    }

    #ifdef __GNUC__

    #else

    // This line should not compile in my opinion.
    cout << i << endl;

    #endif

    return 1;

    }

    Thanks. Don't get too rowdy...
    Chris.

    You're gonna go blind staring into that box all day.

  2. #2
    Join Date
    Jun 2002
    Location
    Letchworth, UK
    Posts
    1,020
    It really depends on which version of the C++ standard the compiler is based on. If it is the later standard, the scope is only within the loop. If it is the earlier standard, the scope is within the enclosing block.

    The arguments were probably based on the different compilers which were based on different standards; hence the confusion.
    Succinct is verbose for terse

  3. #3
    Join Date
    Jun 2002
    Location
    Germany
    Posts
    1,557

    Thumbs up

    Thanks for clearing it up, cup.

    Nowadays I just use the following:

    register int i;

    for(i = 0; i < 10; i++)
    {
    cout << i << endl;
    }

    All compilers can handle this one. Nevertheless, I wish newer compilers were consistent with the newer standard.

    Chris.

    You're gonna go blind staring into that box all day.

  4. #4
    Join Date
    Apr 2000
    Location
    Frederick, Maryland
    Posts
    507
    According to C++ Standard 6.5.3.2

    If the for-init-statement is a declaration, the scope of the name(s) declared extends to the end of the for-statement
    So this is legal code in C++ although VC 6 gives error in this

    Code:
    for (int i = 0; i < 10; i++)
       // do something
    
    for (int i = 0; i < 10; i++)
      // do something
    In fact you can make your code portable this way

    Code:
    int i;
    
    for (i = 0; i < 10; i++)
       // do something
    
    for (i = 0; i < 10; i++)
      // do something
    Hope it helps.

  5. #5
    Join Date
    Jun 2002
    Posts
    33
    I think the VC++ compiler only limits variables to a scope when they are declared within the body of a for, while, do or switch statement. So while:

    for (int i=0; i<10; i++)
    {
    //Do something.
    }

    for (int i=0; i<10; i++)
    {
    //Do something.
    }

    is INVALID because both integers called i are declared OUTSIDE the statements body { }, which means they are not limited to the scope of the loop (which makes sense when you think about it). Remember that the first param of a for loop is initialisation, and it is done BEFORE the program enters the loop (makes even more sense IMO). The other params are used IN THE STATEMENTS BODY i.e. every time it loops. The statement above is trying to do this basically (in effect):

    int i;
    for (i=0; i<10; i++)
    //blah

    int i
    for (i=0; i<10; i++)
    //blah

    which is obviously going to cause a compiler error.

    Alan.
    Last edited by Chambers; July 3rd, 2002 at 02:27 PM.

  6. #6
    Join Date
    Sep 2001
    Location
    San Diego
    Posts
    2,147
    ...Good question.

    See MSDN article Q167748 which describes this very problem.

    In fact it only became a problem when Microsoft introduced some language extensions back in version 5.0 that extended the scope of the variable beyond the for-loop.

    You can disable this behaviour (and all language extensions) to limit the variable to the loop using the /Za compiler switch.

    This (now default) behaviour does not comply with the ANSI/ISO C++ standard (there are many other things that don't comply too).

    Hope this helps,

    - Nigel

  7. #7
    Join Date
    Sep 2001
    Location
    San Diego
    Posts
    2,147
    ...I should also point out that using the /Za compiler option is not without its own problems.

    See the Q167748 article for a specific workaround for the 'problem' you describe.

    - Nigel

  8. #8
    Join Date
    Apr 1999
    Posts
    27,449
    Regardless of what VC++ does, this code is legal C++:
    Code:
    int main()
    {
      for (int i=0; i<10; i++) { }
      for (int i=0; i<10; i++) { }
    }
    The scoping rules were clearly defined by Zeeshan's post. Also, go to http://www.comeaucomputing.com/tryitout and enter code in their on-line compiler, which adheres to the ANSI C++ specification. You will see that the VC++ way of doing this causes an error.
    Code:
    int main()
    {
      for (int i = 0; i < 10; i++ )  {}
      //...
      for (i = 0; i < 10; i++) { }
    }
    Regards,

    Paul McKenzie

  9. #9
    Join Date
    Jun 2002
    Location
    Germany
    Posts
    1,557
    Thanks to everyone.

    It is pleasing that so many experienced developers shared their knowledge.

    When I was much youngerin the early 90's, I first learned C++. There was no real specification then. I learned that the scope of a loop variable was, in fact, confined to the lines within the loop. Furthermore, it is allowed to declare a variable of the same name in back-to-back loops, as many developers pointed out in the previous text.

    I tend to agree that the answers of Paul McKenzie and Zeeshan are in conformance with the new language specification. However if portability is an issue, one might have to remain conservative and avoid relying on the tight scope.

    The different behavior of various compilers, which are both of such incredibly high quality, is simply something that has to be watched out for (I'm, of course talking about VC and GNU). Unfortunately, I still code more bugs than the compilers artificially create in the translation.

    Thanks again for all the information exchange.

    Chris.

    You're gonna go blind staring into that box all day.

  10. #10
    Join Date
    Jun 1999
    Location
    San Diego, CA
    Posts
    600
    Regardless of what C++ standard says or whether the code can compile by a small potato compiler or not, it is NEVER a good idea to jam a variable declaration into a for statement.

    Plus you really have nothing to gain. Whether the loop variable is declared together with other local variables at the beginning of the function, or some where before the for statement, or within the for statement. The code is implemented exactly the same. The following two code snippets will compile into EXACTLY the SAME executable code:
    int foo()
    {
    int result;
    //other variables
    int i;

    //...
    for (i=0; i<16; i++)
    {
    //...
    }
    return result;
    }

    int foo()
    {
    int result;
    //other variables
    //int i;

    //...
    for (int i=0; i<16; i++)
    {
    //...
    }
    return result;
    }

    Also, notice that the spot before the first ; within a for statement is reserved for variable initialization list, you can do something like this:
    for (i=0,j=1,k=2; i<16; i++,j++,k++)
    {
    //...
    }

    If you insert a variable declaration there, you have deprived yourself the ability to put an initialization list there for those already declared variabled.

    I challenge any one to write a for statement in which you declare two variables of different types. Can any one do it? No one can.

    I also challenge any one to write a for statement in which you declare variables, AND also initialize variables already declared previously. Can any one do this? No one can.

  11. #11
    Join Date
    Apr 1999
    Posts
    27,449
    [QUOTE]Originally posted by Anthony Mai
    Regardless of what C++ standard says...

    Of course the standard means nothing to you.

    ... or whether the code can compile by a small potato compiler or not...

    That comment is so ridiculous, it deserves no response except one: What do you have against other compilers which do things correctly?Ever get a copy of "Windows Developers Journal" and hear of "VC++ Bug of the Month"?

    The code can't be compiled on any UNIX compiler that I've come across. It doesn't matter whether the compiler is "small potatoes" or "big potatoes" or "medium sized onions". If it can't compile it, it is not ANSI standard. Plain and simple.

    Also, the original post was whether the code is valid or not. That was answered (most adequately by Zeeshan). It was not a question about programming style or how many compiler sales Microsoft has made.

    Regards,

    Paul McKenzie

  12. #12
    Join Date
    Apr 1999
    Posts
    27,449
    Originally posted by dude_1967
    Thanks to everyone.

    It is pleasing that so many experienced developers shared their knowledge.

    When I was much youngerin the early 90's, I first learned C++. There was no real specification then. I learned that the scope of a loop variable was, in fact, confined to the lines within the loop. Furthermore, it is allowed to declare a variable of the same name in back-to-back loops, as many developers pointed out in the previous text.

    I tend to agree that the answers of Paul McKenzie and Zeeshan are in conformance with the new language specification. However if portability is an issue, one might have to remain conservative and avoid relying on the tight scope.

    The different behavior of various compilers, which are both of such incredibly high quality, is simply something that has to be watched out for (I'm, of course talking about VC and GNU). Unfortunately, I still code more bugs than the compilers artificially create in the translation.

    Thanks again for all the information exchange.

    Chris.

    Your right about the portabiliy issue. Right now, I have to compile code with VC++, and under different versions of UNIX. I can't tell you how many times I've had to edit code to "factor out" the loop initialization so as to compile the code under UNIX.

    So far, I've yet to come acrosss a UNIX C++ compiler that can compile the VC++ (i.e. wrong) version of the for() loop.

    Regards,

    Paul McKenzie

  13. #13
    Join Date
    Jun 2002
    Posts
    224

    Just for fun (Anthony, please take note :) )

    The old book I have (TC++PL, 2nd edition) says like this:
    Code:
    
    iteration-statement:
    	...
    	for ( for-init-statement; condition(opt); expression(opt) ) statement
    condition:
    	expression
    type-specifier declarator = expression
    
    That means one can write:
    Code:
    int condition( int ai )
    {
      // do something creative
      return ai;
    }
    for ( int i = 0; int j = condition(i); i++ )
    {
      // use i and j
    }
    VC++ does not compile the code above (missing int before; ). It’ll be interesting to find out what the others compilers say about this piece of code.
    Is this of any practical use? Maybe…
    One can say it looks ugly... Maybe...
    ZDF

    What is good is twice as good if it's simple.
    "Make it simple" is a complex task.

  14. #14
    Join Date
    Jun 1999
    Location
    San Diego, CA
    Posts
    600
    Paul:

    When you follow up, make sure you read my message first.

    Which part of the code I cited can not be compiled on UNIX?

    I am against putting variable declarations inside for statements. If you do not declare variable within the for statement, every thing will work just fine and every compiler can compile it.

    It is when you declare a variable in the for statement that ambiguity of what scope that variable belongs to raises, and you have to modify to cope with different compilers. It is a trouble that you invite in the first place by declaring something like for(int i=0;.

    BTW, I do work on both UNIX and Win32 at the same time, on a daily basis.

    And finally it is never without a reason that big potato compilers sale much better than small potato ones. It's something developers voted using their money.

  15. #15
    Join Date
    Apr 2000
    Location
    Frederick, Maryland
    Posts
    507
    it is NEVER a good idea to jam a variable declaration into a for statement
    Just want to reply one thing in response of this. Take a look at Item 32 of Effective C++ 2nd edition by Scott Meyers.

    Item 32: Postpone variable definitions as long as possible.
    Hope it helps.

Page 1 of 4 1234 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured