'for'循环初始声明中的静态变量

时间:2014-01-14 18:37:37

标签: c static c99

想知道为什么我不能在for循环初始化中声明静态变量,如下所示,

for(static int i = 0;;)

使用我的C99标准编译器编译上面的循环语句代码,我看到以下错误,

error: declaration of static variable ‘i’ in ‘for’ loop initial declaration

4 个答案:

答案 0 :(得分:6)

C不允许

C11dr 6.8.5 迭代声明 3

for语句的声明部分只应声明具有存储类autoregister”的对象的标识符。

(不是static


通常,代码不会使形成能够具有static的迭代器。


存储类说明符:

typedef
extern
static
_Thread_local
auto
register

答案 1 :(得分:5)

for声明中声明变量的目的是将其范围缩小到循环块。

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

当您将局部变量声明为static并初始化它时,初始化仅在首次运行代码时完成一次。

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

因此,在循环声明中初始化的for变量static循环只会被初始化一次!

// 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;;) {
  // ...
}

答案 2 :(得分:2)

实际上,这在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;
}

目的是为日志记录api提供一个无缝包装器(其入口点由LOG()宏全局提供),以便该日志行只在程序的生命周期内执行一次。

执行程序提供以下内容:

$ ./testLogOnce
ciao 1
ciao 2

我认为C ++标准允许吗?

答案 3 :(得分:1)

你想要完成什么?

如果您尝试访问i循环之外的变量for,则必须在for循环之外声明它:

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

如果您希望仅在第一次调用函数时执行for循环,请创建一个static布尔变量来处理该函数。

static bool firstTime = true;

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

    firstTime = false;
}