VS6 vs 2005 [modified]
-
Hi, Does anybody know if there is a switch or patch to make VC6 adhere to the (correct) scope rules for C++ like in the 2005 version? Example: for ( int i; i < 10; ++i) foo++; for ( int i; i < 20; ++i) bar++; In VS6 i will not go out of scope at the end of the for loop and you will get a redeclaration error at the second int. While in 2005 if you were to delete the second int (to satisfy VC6) you'd get an undeclared identifier error. Jay
modified on Tuesday, March 10, 2009 10:19 PM
-
Hi, Does anybody know if there is a switch or patch to make VC6 adhere to the (correct) scope rules for C++ like in the 2005 version? Example: for ( int i; i < 10; ++i) foo++; for ( int i; i < 20; ++i) bar++; In VS6 i will not go out of scope at the end of the for loop and you will get a redeclaration error at the second int. While in 2005 if you were to delete the second int (to satisfy VC6) you'd get an undeclared identifier error. Jay
modified on Tuesday, March 10, 2009 10:19 PM
Not a switch or patch, but I have seen a macro that was devised to handle that problem. Unfortunately I didn't make a note of it so I can't pass it on to you. If memory serves, I saw here on Code Project in the Coding Horrors forum. Someone had posted it due to its ugliness. Only later in the discussion did another poster reveal what its purpose was. The actual Horror of it was that the person who put in the file where the OP of the thread found it failed to comment WTF it was. It was months ago, I believe. Sometime before August 2008. I tried peeking in the forum but it doesn't seem to be working well today for posts that old.
BDF People don't mind being mean; but they never want to be ridiculous. -- Moliere
-
Hi, Does anybody know if there is a switch or patch to make VC6 adhere to the (correct) scope rules for C++ like in the 2005 version? Example: for ( int i; i < 10; ++i) foo++; for ( int i; i < 20; ++i) bar++; In VS6 i will not go out of scope at the end of the for loop and you will get a redeclaration error at the second int. While in 2005 if you were to delete the second int (to satisfy VC6) you'd get an undeclared identifier error. Jay
modified on Tuesday, March 10, 2009 10:19 PM
-
I'm not meaning to pick on your code, but why don't you write better scoped code and declarations that won't cause this, so you don't have this problem?
int i;
for (i=0; i < ++i)
{
foo++;
}
for (i=0; i & lt; ++i)
{
bar++
}Because it's just an absolute minimum example to demonstrate the bug. But besides the fact that if there were much code or calls between the two loops, by making the loop variable more local in scope an optimizing compiler would make it a register variable. Or because many of the parallel threading tools require it to be done this way, again for optimizing. Also, while what your are talking about was the standard for C it is frowned upon in C++ which most style guides recomend declaring variables where they are first used and they are preferred to have as local scope as possible. Jay
-
Because it's just an absolute minimum example to demonstrate the bug. But besides the fact that if there were much code or calls between the two loops, by making the loop variable more local in scope an optimizing compiler would make it a register variable. Or because many of the parallel threading tools require it to be done this way, again for optimizing. Also, while what your are talking about was the standard for C it is frowned upon in C++ which most style guides recomend declaring variables where they are first used and they are preferred to have as local scope as possible. Jay
Well, I'm definitely not a C++ programmer, but I prefer C, and have even programmed using a C++ compiler but followed C standards. You could be more concise with the scoping then with something like this:
{
int i;
for (i=0,.....)
foo++;
}{
int i;
for i=0;....)
bar++;
} -
Hi, Does anybody know if there is a switch or patch to make VC6 adhere to the (correct) scope rules for C++ like in the 2005 version? Example: for ( int i; i < 10; ++i) foo++; for ( int i; i < 20; ++i) bar++; In VS6 i will not go out of scope at the end of the for loop and you will get a redeclaration error at the second int. While in 2005 if you were to delete the second int (to satisfy VC6) you'd get an undeclared identifier error. Jay
modified on Tuesday, March 10, 2009 10:19 PM
Hi Jay, I've done some further research on this issue because it of interest to me as well. There's an upcoming (C/) C++ project that may use VS6 or possibly VS2008. Maybe I'll need compatibility with both. I've found several options that could be used for handling this. I'll just list them without discussion of pro/con. I'm sure you can make your own decision which if any to use. Enclose for loops in artificial blocks:
{for (int i; i < 10; ++i)
{
foo++;
}}Move loop variable above the loops, as uzziah0 suggested. This macro supposedly solves the problem. More than one source suggested it but I've never tried it. The one I referred to in my earlier post was uglier, as I recall, but maybe this was it. I found it suggested multiple times.
#define for if(false); else for
One of the people who suggested it added, "It's in our master win32 config file right after disabling warning 4786!" There may also be a compiler option. I haven't researched this, but I'll quote a forum post I found somewhere else.VC++ 6 has an option (/Za) that enforces the correct scope for
variables defined in the header of a for loop (etc.) The problem is
that when you turn this switch on, it enforces a number of other
rules, and its standard headers (among other things) won't compile
when those rules are enforced -- the result is that even though the
compiler itself has the capability, the remainder of the
implementation renders it unusable.Hope something in this mish-mash will work for you!
BDF People don't mind being mean; but they never want to be ridiculous. -- Moliere
-
Hi Jay, I've done some further research on this issue because it of interest to me as well. There's an upcoming (C/) C++ project that may use VS6 or possibly VS2008. Maybe I'll need compatibility with both. I've found several options that could be used for handling this. I'll just list them without discussion of pro/con. I'm sure you can make your own decision which if any to use. Enclose for loops in artificial blocks:
{for (int i; i < 10; ++i)
{
foo++;
}}Move loop variable above the loops, as uzziah0 suggested. This macro supposedly solves the problem. More than one source suggested it but I've never tried it. The one I referred to in my earlier post was uglier, as I recall, but maybe this was it. I found it suggested multiple times.
#define for if(false); else for
One of the people who suggested it added, "It's in our master win32 config file right after disabling warning 4786!" There may also be a compiler option. I haven't researched this, but I'll quote a forum post I found somewhere else.VC++ 6 has an option (/Za) that enforces the correct scope for
variables defined in the header of a for loop (etc.) The problem is
that when you turn this switch on, it enforces a number of other
rules, and its standard headers (among other things) won't compile
when those rules are enforced -- the result is that even though the
compiler itself has the capability, the remainder of the
implementation renders it unusable.Hope something in this mish-mash will work for you!
BDF People don't mind being mean; but they never want to be ridiculous. -- Moliere
You're right, the /Za option doesn't work well because the MS libraries have lots of errors in them with that option. I tried the macro you found and it works in both VS6 and VS2005 to make them function the same (and adhere to the language standard). I did modify it slightly though just to include it in and ifdef as follows: #if (_MSC_VER == 1200) // Microsoft Visual Studio 6.0 // fix variable scope bug in for loops #define for if (false); else for #endif // (_MSC_VER == 1200) You could change the if to use the true case but doing so will cause issues with joining to the closest ELSE in some cases and the NOP will be optimized out so the if will essentially disappear the way it is anyway. Jay
-
Because it's just an absolute minimum example to demonstrate the bug. But besides the fact that if there were much code or calls between the two loops, by making the loop variable more local in scope an optimizing compiler would make it a register variable. Or because many of the parallel threading tools require it to be done this way, again for optimizing. Also, while what your are talking about was the standard for C it is frowned upon in C++ which most style guides recomend declaring variables where they are first used and they are preferred to have as local scope as possible. Jay
feanorgem wrote:
Also, while what your are talking about was the standard for C it is frowned upon in C++ which most style guides recomend declaring variables where they are first used and they are preferred to have as local scope as possible.
Who says that? That's rubbish
-
feanorgem wrote:
Also, while what your are talking about was the standard for C it is frowned upon in C++ which most style guides recomend declaring variables where they are first used and they are preferred to have as local scope as possible.
Who says that? That's rubbish
Well one vote in 6 billion is hardly a majority. Bjarne Stroustrup and the members of the ANSI C++ standard board added the feature (borrowed form other language definitions) because it is preferred otherwise it wouldn't have been added. Plus it is the basis of creating C++ which is an OOP and therefore promotes encapsulation. Intel, Microsoft, Cilk, any compiler vendor or writer and far to many style guides to list. I can't think of a single reference that promotes making variables more global as preferred to more local. http://www.parashift.com/c++-faq-lite/coding-standards.html http://www.icce.rug.nl/documents/cplusplus/ Feel free though to come up with a single reference that doesn't promote encapsulation, OOP and localization and therefore a reason for creating C++ in the first place.
-
You're right, the /Za option doesn't work well because the MS libraries have lots of errors in them with that option. I tried the macro you found and it works in both VS6 and VS2005 to make them function the same (and adhere to the language standard). I did modify it slightly though just to include it in and ifdef as follows: #if (_MSC_VER == 1200) // Microsoft Visual Studio 6.0 // fix variable scope bug in for loops #define for if (false); else for #endif // (_MSC_VER == 1200) You could change the if to use the true case but doing so will cause issues with joining to the closest ELSE in some cases and the NOP will be optimized out so the if will essentially disappear the way it is anyway. Jay
I also found a reference that mentions a different compiler option that fixes VC7. You can use /Zc:forscope which won't create the library issues but will make the for scope rules adhere to the language standard. I did check and this option is not available in VS6 but I didn't verify VS7. Jay