update: I've now re-tested both a simplified test case and the full code with the shared names reinstated, and it works correctly. There probably was some other error somewhere else in my code which is now fixed. Sorry for wasting your time and effort; will never post without a working test case in the future. Mea culpa.
I have a C++ function which I call repeatedly. It has the following snippet in it
switch(c)
{
case 1:
{
static int i = 0;
if ( ... ) { i = 0; }
....
break;
}
case 2:
{
static int i = 0;
if ( ... ) { i = 0; }
....
break;
}
case 3:
{
static int i = 0;
if ( ... ) { i = 0; }
....
break;
}
}
The idea is that it must remember its state per each case, and sometimes it must reset it.
It didn't work properly. When I was debugging it (MSVC++ 2010 Express Edition) I noticed that each i
was not behaving independently and their values were changing seemingly by themselves; moreover when the re-set condition was hit, the corresponding if
was entered OK but the i = 0;
statement was just ... skipped over!!! And the "locals" window showed i
with its previous value, unchanged (while the current statement was the next one, still inside the if
). Other statements inside the if
were executing properly.
When I renamed each i
with a unique name (i1
, i2
, i3
), the problem went away.
Is this some bug, or some language feature that I should know? I thought each block { ... }
defines independent scope. What is going on here? Would it work in C?
edit: sorry for not constructing the test case. Will do so, and report back later.
This sounds like a bug in your code or interpretation. I can well imagine a "watch window" feature in your debugger getting this wrong, since blocks don't have names and will therefore be difficult to identify in text.
Local variables with static
storage duration are bound by block scope.
Here's proof that they do not have function scope:
[C++11: 3.3.5/1]:
Labels (6.1) have function scope and may be used anywhere in the function in which they are declared. Only labels have function scope.
And here's a practical demonstration:
#include <iostream>
void f(const int i)
{
switch (i) {
case 3: {
static int x = 0;
std::cout << x;
x = 3;
std::cout << x << ' ';
break;
}
case 4: {
static int x = 0;
std::cout << x;
x = 4;
std::cout << x << ' ';
break;
}
}
}
int main()
{
f(3);
f(4);
}
// Output: 03 04
This shows that when the second case is entered, you are working with a different local, static variable x
. Otherwise you would see 03 34
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With