0

I was reading the answer to another SO question regarding the declaration of variables inside for loops. The accepted answer brings this very useful code sample, which I extend slightly by adding an extra for loop externally:

for (int j=0; j<N; j++)
{
    int i, retainValue;
    for (i=0; i<N; i++)
    {
       int tmpValue;
       /* tmpValue is uninitialized */
       /* retainValue still has its previous value from previous loop */

       /* Do some stuff here */
    }
    /* Here, retainValue is still valid; tmpValue no longer */
}

As thigs are, tmpValue is meant to be used only inside the inner for, and its existance would cease at the end of the inner loop's life. However, because the loop is cascaded within another one, and assuming I'd actually like tmpValue to retain its value throughout the whole external loop execution, would it be good practice to assign the static keyword to tmpValue?

for (int j=0; j<N; j++)
{
    int i, retainValue;
    for (i=0; i<N; i++)
    {
       static int tmpValue;
       /* tmpValue is uninitialized */
       /* retainValue still has its previous value from previous loop */

       /* Do some stuff here */
    }
    /* Here, retainValue is still valid; tmpValue no longer */
}

The reason I ask is that some arguments in favour of tmpValue to be defined inside the inner loop had to do with readability and optimality of code. I am not sure neither are still true with my second example.

raggot
  • 992
  • 15
  • 38
  • 4
    _would it be good practice to assign the static keyword_ No! Move it outside the inner loop. –  Jan 25 '18 at 09:46
  • if you really need to keep it, then you can always return it – UKMonkey Jan 25 '18 at 09:46
  • You should declare the variable in scope it will be used in. As you need to retain tmpValue for the outer for loop,you just need to declare it there instead of in the inner one. – Nitesh Jan 25 '18 at 09:47
  • 1
    Avoid static variables. They make reasoning about programs much harder and break parallelism. – n. m. could be an AI Jan 25 '18 at 09:55

3 Answers3

1
for (int j=0; j<N; j++)
    {
        int i, retainValue;
        for (i=0; i<N; i++)
        {
           static int tmpValue;
           // tmpValue is uninitialized only on first run of this piece of code. 
           // If you run this "for" procedure again tmpValue will be already
           // initialized and will have last value

        }// tmpValue is not destroyed here, but becomes inaccessible
    }

So if you need your tmpValue outside the for loop. just declare it outside.

int tmpValue;
for (int j=0; j<N; j++)
....
Xplatforms
  • 2,102
  • 17
  • 26
  • Correct. This is also the readable solution. Since it's declared just before the loop, C++ programmers instantly see that the value is retained over the loop. The one thing I spot (but that's really a problem in the question) is a lack of an initial value. For per-iteration variables, that can be acceptable (if the first use initializes it). ` tmpValue` must be _updated_ and that means a read-modify-write loop. The initial read breaks if uninitialized. – MSalters Jan 25 '18 at 11:56
  • From this answer I don't actually see a reason for preferring the second to the first. Overall the only difference is that tmpValue in the first case remains inaccessible, which I see as a good thing if that variable's use must be contained to the inner loop. Actually the point of placing it in the inner loop is precisely so that it's inaccessible outside it. But what if its value needs to be retained at each iteration of the external one? – raggot Jan 25 '18 at 12:22
0

What you have done is completely break the ability to call your function with multiple uses by adding static (and threads, but let's keep with the single threaded idea for now for simplicity). Let me show by example.

doLoop(a);
doLoop(b);

Looks like it's doing something with just a and b; but if I wanted to start from scratch again and doLoop(c) I can't. If however I return the value that I was using; and give it a default value of 0, then suddenly I can do

auto x = doLoop(a);
x = doLoop(a, x);
auto y = doLoop(c);

This completely separates the LOGIC in the function from the DATA; which is something that will almost always make life easier in the long run.

UKMonkey
  • 6,941
  • 3
  • 21
  • 30
  • Not sure why they downvoted you, I +1 you for the idea although it doesn't directly answer my question. You basically propose to avoid using the external loop and make a function with output instead. I think it complicates the code a bit in terms of readability. A concatenated loop seems clearer to me. This seems to be a better philosophy for multi-threading though – raggot Jan 26 '18 at 09:54
  • I may have misread your question that your tmpValue could exist outside the internal loop, but inside the first; but the static variable is most defiantly not the way to go in this case (for the reasons above) – UKMonkey Jan 26 '18 at 09:56
-2

static variable does have the lifetime of program, but they still follows the scope rules.

nevihs
  • 991
  • 1
  • 12
  • 23