Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Separate scope for switch cases with static variables with the same name [closed]

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.

like image 915
darveter Avatar asked Dec 26 '22 12:12

darveter


1 Answers

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.

Live demo using GCC 4.8; I get the same result with Visual Studio 2012.

like image 78
Lightness Races in Orbit Avatar answered Jan 14 '23 07:01

Lightness Races in Orbit