Question

Would like to know why cannot I declare a Static variable in for loop initialization as shown below,

for(static int i = 0;;)

Compiling the above loop statement code with my C99 standard compiler I see the below error,

error: declaration of static variable ‘i’ in ‘for’ loop initial declaration
Was it helpful?

Solution

C does not allow it

C11dr 6.8.5 Iteration statements 3

"The declaration part of a for statement shall only declare identifiers for objects having storage class auto or register".

(not static)


Typically code would not benefit form being able to have an iterator that is static.


storage-class-specifier:

typedef
extern
static
_Thread_local
auto
register

OTHER TIPS

The purpose of declaring a variable in the for declaration is narrowing its scope to the loop block.

// i does not exist here
for (int i = 0;;) {
  // i exists here
}
// i does not exist here

When you declare a local variable as static and initialize it, the initialization is done only once, when the code is first run.

{
  static int i = 0; // i will be set to 0 the first time this is called
  i++;
}

So a for loop with a static variable that is initialized in the loop declaration will only be initialized once!

// i will not be initialized to 0 the second time this loop runs and we cannot
// initialize it here, before the loop block
for (static int i = 0;;) {
  // ...
}

Actually, this compiles and works as expected in g++ 4.4.3.

#include <stdio.h>

#define LOG() testPrintfPtr
#define LOG_ONCE() \
    for (static bool __only_once_ = 0; !__only_once_; __only_once_ = true) \
        LOG()

struct test {
    void debug(const char *str) {
        printf("%s\n", str);
    }
};

test *testPrintfPtr = new test();

int main() {
    for (int i = 0; i < 10; ++i)
        LOG_ONCE()->debug("ciao 1");

    LOG_ONCE()->debug("ciao 2");

    return 0;
}

The purpose is to provide a seamless wrapper to a logging api (whose entry point is provided globally by the LOG() macro) so that that log line is only executed once during the program's lifetime.

Executing the program gives the following:

$ ./testLogOnce
ciao 1
ciao 2

I assume the C++ standard allows it?

What are you trying to accomplish?

If you're trying to be able to access the variable i outside the for loop, you'll have to declare it outside the for loop:

int i;
for(i = 0; ; )
{
    …
}
printf("%d\n", i);

If you'd like to have the for loop execute only the first time a function is called, create a static boolean variable to handle that.

static bool firstTime = true;

if(firstTime)
{
    for(int i = 0; ; )
    {
        …
    }

    firstTime = false;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top