473,219 Members | 1,502 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,219 software developers and data experts.

int var declared in "for" not local?

I'm getting a bizarre error with this code:

...
case WM_COMMAND:
{
switch (LOWORD(wParam)) // switch (control ID)
{
...
case IDC_RAIN_ENABLE_SIMPLE:
{
if (BN_CLICKED == HIWORD(wParam))
{
for ( int i = 0 ; i < 11 ; +i)
{
ShowWindow(GetDlgItem(hDlg, RainControls[i]), SW_SHOW);
}

for ( int i = 11 ; i < 25 ; +i) // !!! ERROR !!! ERROR !!!
ERROR !!!
{
ShowWindow(GetDlgItem(hDlg, RainControls[i]), SW_HIDE);
}
}
break;
}
...
break;
}
...
break;
}
...
break;
...
My compiler here at work (MS VC++ 6.0) balks at the line marked
"ERROR" above. It says this is a "redefinition" of i .
How can this be? Isn't i local to each for statement? Doesn't
the closing curly brace of the "0 to 10" for statement make i
go out of scope? So defining a new i in the next for statement
should be perfectly ok, shouldn't it?

Am I missing something here, or is this a bug in MS VC++ 6.0?

--
Puzzled,
Robbie Hatley
lone wolf intj at pac bell dot net
Dec 16 '05 #1
12 2057

Robbie Hatley wrote:
I'm getting a bizarre error with this code:

...
case WM_COMMAND:
{
switch (LOWORD(wParam)) // switch (control ID)
{
...
case IDC_RAIN_ENABLE_SIMPLE:
{
if (BN_CLICKED == HIWORD(wParam))
{
for ( int i = 0 ; i < 11 ; +i)
{
ShowWindow(GetDlgItem(hDlg, RainControls[i]), SW_SHOW);
}

for ( int i = 11 ; i < 25 ; +i) // !!! ERROR !!! ERROR !!!
ERROR !!!
{
ShowWindow(GetDlgItem(hDlg, RainControls[i]), SW_HIDE);
}
}
break;
}
...
break;
}
...
break;
}
...
break;
...
My compiler here at work (MS VC++ 6.0) balks at the line marked
"ERROR" above. It says this is a "redefinition" of i .
How can this be? Isn't i local to each for statement? Doesn't
the closing curly brace of the "0 to 10" for statement make i
go out of scope? So defining a new i in the next for statement
should be perfectly ok, shouldn't it?

Am I missing something here, or is this a bug in MS VC++ 6.0?


It's a non-conformancy in VC++ 6. Their standard solution is to upgrade
to VC.NET, which might be expensive or otherwise undesirable, to wrap
for loops in a set of curly braces, which is ugly, or to use a macro:

#define for if(0);else for

Cheers! --M

Dec 16 '05 #2

"mlimber" <ml*****@gmail.com> wrote in message

news:11*********************@g43g2000cwa.googlegro ups.com...

Robbie Hatley wrote:
...
My compiler here at work (MS VC++ 6.0) balks at the line marked
"ERROR" above. It says this is a "redefinition" of i .
How can this be? Isn't i local to each for statement? ...
It's a non-conformancy in VC++ 6.


I see! Thanks for the info. Looks like MS is handling
var. decls. in for parens. the same way as some old
implimentations of C did, if I remember correctly.
(Wasn't this the way K&R C did it?) I'll just have to
remember that the scope of i is the block ENCLOSING
the for statement.

I think the way I'll handle that is like so:

case BLAT:
{
int i;
for ( i = 0; i < 11; ++i )
{
DoSomeStuff(Splat[i]);
}
for ( i = 11; i < 25; ++i )
{
DoOtherStuff(Splat[i]);
}
break;
}

Yes, that works.

--
Cheers!
Robbie Hatley
lone wolf intj at pac bell dot net
Dec 16 '05 #3
mlimber <ml*****@gmail.com> wrote:

Robbie Hatley wrote:
for ( int i = 0 ; i < 11 ; +i)
{
ShowWindow(GetDlgItem(hDlg, RainControls[i]), SW_SHOW);
}

for ( int i = 11 ; i < 25 ; +i) // !!! ERROR !!! ERROR !!!
ERROR !!!
{
ShowWindow(GetDlgItem(hDlg, RainControls[i]), SW_HIDE);
}

My compiler here at work (MS VC++ 6.0) balks at the line marked
"ERROR" above. It says this is a "redefinition" of i .
How can this be? Isn't i local to each for statement? Doesn't
the closing curly brace of the "0 to 10" for statement make i
go out of scope? So defining a new i in the next for statement
should be perfectly ok, shouldn't it?

Am I missing something here, or is this a bug in MS VC++ 6.0?


It's a non-conformancy in VC++ 6. Their standard solution is to upgrade
to VC.NET, which might be expensive or otherwise undesirable, to wrap
for loops in a set of curly braces, which is ugly, or to use a macro:

#define for if(0);else for


Additionally, even with VC.NET 2003, you must pass a commandline option
to the compiler to enforce this rule:

/Zc:arg1[,arg2] C++ language conformance, where arguments can be:
forScope - enforce Standard C++ for scoping rules
wchar_t - wchar_t is the native type, not a typedef

--
Marcus Kwok
Dec 16 '05 #4
Marcus Kwok wrote:

Additionally, even with VC.NET 2003, you must pass a commandline option
to the compiler to enforce this rule:

/Zc:arg1[,arg2] C++ language conformance, where arguments can be:
forScope - enforce Standard C++ for scoping rules
wchar_t - wchar_t is the native type, not a typedef


Well, yes and no. If you don't set that option, the VC++ 2003 compiler
will try to figure out what you mean. I.e. if you do this:

for (int i = 0; i < 10; ++i) a[i] = i;
cout << i << endl;

then the output will be "10", but if you do this:

for (int i = 0; i < 10; ++i) a[i] = i;
int i = 37;
cout << i << endl;

then the output will be "37".

--
Mike Smith
Dec 16 '05 #5
Mike Smith <mi*****************@acm.org> wrote:
Marcus Kwok wrote:

Additionally, even with VC.NET 2003, you must pass a commandline option
to the compiler to enforce this rule:

/Zc:arg1[,arg2] C++ language conformance, where arguments can be:
forScope - enforce Standard C++ for scoping rules
wchar_t - wchar_t is the native type, not a typedef
Well, yes and no. If you don't set that option, the VC++ 2003 compiler
will try to figure out what you mean. I.e. if you do this:

for (int i = 0; i < 10; ++i) a[i] = i;
cout << i << endl;

then the output will be "10"


Yes, though this is not standard C++.
but if you do this:

for (int i = 0; i < 10; ++i) a[i] = i;
int i = 37;
cout << i << endl;

then the output will be "37".


Yes. I get a warning, but the output is still 37 as you say:

#include <iostream>

int main()
{
int a[10];

for (int i = 0; i < 10; ++i) { // <-- line 7
a[i] = i;
}

int i = 37; // <-- line 11

std::cout << i << '\n'; // <-- line 13

return 0;
}

test.cpp(13) : warning C4288: nonstandard extension used : 'i' : loop
control variable declared in the for-loop is used outside the for-loop
scope; it conflicts with the declaration in the outer scope
test.cpp(11) : definition of 'i' used
test.cpp(7) : definition of 'i' ignored
With /Zc:forScope:

test.cpp(13) : warning C4258: 'i' : definition from the for loop is
ignored; the definition from the enclosing scope is used
test.cpp(7) : definition of 'i' ignored
test.cpp(11) : definition of 'i' used

--
Marcus Kwok
Dec 17 '05 #6
On Fri, 16 Dec 2005 20:05:09 GMT, "Robbie Hatley"
<bo*********@no.spam.com> wrote:
I think the way I'll handle that is like so:

case BLAT:
{
int i;
for ( i = 0; i < 11; ++i )
{
DoSomeStuff(Splat[i]);
}
for ( i = 11; i < 25; ++i )
{
DoOtherStuff(Splat[i]);
}
break;
}

Yes, that works.


The official Microsoft workaround is:

#define for if(0);else for

http://support.microsoft.com/default...b;en-us;167748
Dec 17 '05 #7
"Roland Pibinger" <rp*****@yahoo.com> wrote:
The official Microsoft workaround [for the "variables
declared inside for-loop parentheses are not local" bug]
is:

#define for if(0);else for

http://support.microsoft.com/default...b;en-us;167748


Ok, thanks for the info,

However, I don't think I'll use that particular fix
globally, because the program I'm maintaining at work
is about 325,000 lines of poorly-written C code, converted
to C++ (by me), with another 25,000 lines of C++ code added
in over a couple years by three different maintainance
programmers (including myself). I'm afraid somewhere,
someone has actually used-and-depended-on the "non-local-for-
loop-variables" effect. If they did this:

int Borogoves(int Brillig[], int Gyre, int Gimble)
{
for (int Mimsy = 0; Mimsy < Gimble; ++Mimsy)
{
if (Gyre == Brillig[Mimsy]) break;
}
return Mimsy;
}

and if I did this:

// in main.h (included in all *.cpp files):
#define for if(0);else for

that would break Borogoves() . It would no longer
even compile.

But I'll keep the workaround in mind for use in smaller
files with few for loops.

--
Robbie Hatley
Tustin, CA, USA
email: lonewolfintj at pacbell dot net
web: home dot pacbell dot net slant earnur slant
Dec 18 '05 #8
Robbie Hatley wrote:

However, I don't think I'll use that particular fix
globally, because the program I'm maintaining at work
is about 325,000 lines of poorly-written C code, converted
to C++ (by me),
What do you mean by "converted to C++" exactly ?
Renaming .c files to .cpp and changing malloc to new,
is a great way to produce unmaintainable code.

It's probably too late now, but IMHO it is better to leave
C files as C and write new stuff as C++ (and link the two
together, which is simple) , until you are ready to fully
re-write a particular unit as good C++.
with another 25,000 lines of C++ code added
in over a couple years by three different maintainance
programmers (including myself). I'm afraid somewhere,
someone has actually used-and-depended-on the
"non-local-for-loop-variables" effect. If they did this:

int Borogoves(int Brillig[], int Gyre, int Gimble)
{
for (int Mimsy = 0; Mimsy < Gimble; ++Mimsy)
{
if (Gyre == Brillig[Mimsy]) break;
}
return Mimsy;
}

and if I did this:

// in main.h (included in all *.cpp files):
#define for if(0);else for

that would break Borogoves() . It would no longer
even compile.


Then you would get compiler errors in every place that
relied on the non-standard behaviour, and you could quickly
fix it all.

However a more subtle problem is:

int foo()
{
int mimsy = 3;
if ( bar() )
{
for (int mimsy = 0; mimsy != 5; ++mimsy)
qux();
return mimsy;
}
}

where the behaviour would silently change with this 'fix'.
Perhaps you could set your compiler to generate assembly
output, then make the fix and do a diff on the generated
assembly. You'd need to be heavily optimising of course,
so that it skips out the extra "if..else" .

Dec 19 '05 #9
"Old Wolf" <ol*****@inspire.net.nz> wrote:
Robbie Hatley wrote:

However, I don't think I'll use that particular fix
globally, because the program I'm maintaining at work
is about 325,000 lines of poorly-written C code, converted
to C++ (by me),
What do you mean by "converted to C++" exactly ?
Renaming .c files to .cpp and changing malloc to new,
is a great way to produce unmaintainable code.


Oh believe me when I tell you, this code I'm maintaining
was plenty "unmaintainable" as a C program, and continues
to be equally "unmaintainable" as a C++ program. Which
makes maintaining it loads of <sarcasm>fun</sarcasm>.

I didn't change any malloc to new. There weren't any,
actually. Lots of GlobalAlloc(), which is the Windows
version of the same thing. I left those alone.

The reasons I converted the program to C++ were two:
1. To get the much stronger typing of MS-VC++ 6's C++
compiler, in place of the weak typing of it's C compiler.
(Which involved fixing about 5000 compiler errors and
10000 linker errors after the switch, due to the author's
mind-boglingly sloppy handling of data types.)
2. To allow use of the C++ STL, especially maps and deques.
(We were adding features that needed maps of structs,
keyed by ints, where the structs contained deques. Doing
that in C would have been unwieldy, but in C++, it was
a breeze.)
It's probably too late now
Waaaaaaay too late.
but IMHO it is better to leave C files as C and write new
stuff as C++ (and link the two together, which is simple)
Why? See above under "stronger typing". After converting
to C++ and fixing the many thousands of compiler and linker
errors which immediately cropped up, my co-workers and I
found that many of the bugs which customers and field-service
reps had be complaining about over the years mysteriously
vanished overnight. The key was, taking the time to figure
out why each data-type conflict was occuring, and to try to
solve it at its source, rather than bandaid it with a
typecast, which is a good way to hide bugs rather than fixing
them.

I agree that if you have a WELL-WRITTEN C program, and
want to add C++ stuff to it (STL, containers, algorithms,
templates, classes, polymorphism, whatever), it's best to
leave the C files alone, and write the new stuff as separate
C++ files and just link 'm in. (Taking measures to ensure
stuff links right, of course, which involves heavy use of
"extern C" among other things.)

However, this particular C program was NOT well-written,
so converting the whole #! to C++ actually helped.
until you are ready to fully re-write a particular unit as
good C++.
That's not going to happen in the life of this program.
The money's not there. The bosses want bug fixes and new
features, not re-factoring.

I wrote about the possible use of the "non-local for vars"
in the program, and my fear of breaking such uses, and
Old Wolf replied:
Then you would get compiler errors in every place that
relied on the non-standard behaviour, and you could quickly
fix it all.
Maybe, maybe not. As you later admited in the same post:
However a more subtle problem is:

int foo()
{
int mimsy = 3;
if ( bar() )
{
for (int mimsy = 0; mimsy != 5; ++mimsy)
qux();
return mimsy;
}
}

where the behaviour would silently change with this 'fix'.
Which is exactly why I'm not going to impliment MS's
recommended fix globally. Like I say, I may use it
in some individual files with few for statements, where
I can clearly see it won't break anything.
Perhaps you could set your compiler to generate assembly
output, then make the fix and do a diff on the generated
assembly. You'd need to be heavily optimising of course,
so that it skips out the extra "if..else" .


Unless one knows i386 assembly rather well, I don't
see how that would help. Two versions of a C++ program
that generate different assembly outputs may be functionally
different... or they may be functionally the same. I don't
know assembly language well enough to tell the difference.
I'd be squinting, mumbling "PUSH here, POP there, MOV here,
ADD there, and what's this NOP doing? Oh, right, nothing...
Um... HELP!!!" No, I think I'll stick to C++.

--
Cheers!
Robbie Hatley
Tustin, CA, USA
email: lonewolfintj at pacbell dot net
web: home dot pacbell dot net slant earnur slant
Dec 19 '05 #10
Robbie Hatley wrote:
"Old Wolf" <ol*****@inspire.net.nz> wrote:
Perhaps you could set your compiler to generate assembly
output, then make the fix and do a diff on the generated
assembly. You'd need to be heavily optimising of course,
so that it skips out the extra "if..else" .


Unless one knows i386 assembly rather well, I don't
see how that would help. Two versions of a C++ program
that generate different assembly outputs may be functionally
different...


The same source code would generate the same assembly each
time it's compiled. If this 'fix' is the only difference, it seems
plausible to me that the assembly generated would be the same
in every case, or similar enough that perusing the results of a 'diff'
will tell you which changes made no difference and which ones
suddenly referenced a different variable.

Dec 19 '05 #11
Robbie Hatley wrote:

The reasons I converted the program to C++ were two:
1. To get the much stronger typing of MS-VC++ 6's C++
compiler, in place of the weak typing of it's C compiler.
(Which involved fixing about 5000 compiler errors and
10000 linker errors after the switch, due to the author's
mind-boglingly sloppy handling of data types.)


A good reason. While we're on this topic, one way that has
succeeded for me in the past is to compile the source with
GCC, and use the free gnu-win32 package to provide the
windows headers so that it will compile. (Or even write your
own header if the project doesn't use much winapi stuff).
GCC is an excellent lint tool :)

Dec 19 '05 #12
Old Wolf wrote:
Robbie Hatley wrote:

The reasons I converted the program to C++ were two:
1. To get the much stronger typing of MS-VC++ 6's C++
compiler, in place of the weak typing of it's C compiler.
(Which involved fixing about 5000 compiler errors and
10000 linker errors after the switch, due to the author's
mind-boglingly sloppy handling of data types.)

A good reason. While we're on this topic, one way that has
succeeded for me in the past is to compile the source with
GCC, and use the free gnu-win32 package to provide the
windows headers so that it will compile. (Or even write your
own header if the project doesn't use much winapi stuff).
GCC is an excellent lint tool :)


You probably well aware of this already, but I've seen code using C++
objects inside memory allocated using malloc() and free(). Unfortunately
, as far as I know it still exists along with all the hanging allocated
memory that it causes, not to mention no constructor calls! So, good
luck and take great care, as the task you're undertaking is fraught with
difficulties that can catch the best of us, (I can only hope that I'm
one of the best).

JB
Dec 20 '05 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Patrick Guio | last post by:
Dear all, I wonder whether anyone might have a better idea/solution to the following. I need an associative container <int,string> for a limited and defined number of values (enum-like) but ir...
1
by: wireless200 | last post by:
I'm running EM on my local box and sql server on a remote internet accessed box. How do I specify a file path for a DTS package to access files on the remote box? For example, to run a local...
8
by: Joe | last post by:
I need an Access application that can search dealers from my dealer list, in a 30 miles distance from the user. You may see many applications like this on the web if you search under "find a...
4
by: Brian Pearson | last post by:
Hi, For a web application, is it possible to use something other than the \bin directory for local assemblies? I do not wish to use the GAC. My end goal is to have multiple websites use the...
1
by: Eric West | last post by:
Hello gurus of the internet- I'm trying to install PHP on a system with MySQL I've had success using MySQL which was installed via "yum install mysql" on my CentOS 4.3 system. My problem is...
7
by: torus | last post by:
Is the aspnet account called "aspnet" for all non-English versions of Windows and IIS?
1
by: pbd22 | last post by:
Hi - I have code that automatically fills tabs on a page. In some cases, a URL path won't be correct (the folder and files don't exist) and, in these cases, I want to catch these exceptions and...
3
by: billelev | last post by:
I'm a relative newbie to java and have encountered a "source not found" error when trying to debug the following section of code (for the ParseException.class). public PaymentDates (String...
15
by: Steve | last post by:
I am having problems getting values out of an array. The array is set as a global array and values are pushed into it as they are read from a JSON file using a "for loop". When the "for loop" is...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
0
by: mar23 | last post by:
Here's the situation. I have a form called frmDiceInventory with subform called subfrmDice. The subform's control source is linked to a query called qryDiceInventory. I've been trying to pick up the...
2
by: jimatqsi | last post by:
The boss wants the word "CONFIDENTIAL" overlaying certain reports. He wants it large, slanted across the page, on every page, very light gray, outlined letters, not block letters. I thought Word Art...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.