在“for”循环中静态变量的初始声明

4

想知道为什么不能像下面这样在for循环初始化中声明静态变量:

for(static int i = 0;;)

使用我的 C99 标准编译器编译上述循环语句代码时,我看到以下错误:
error: declaration of static variable ‘i’ in ‘for’ loop initial declaration

9
因为语言无法支持?在什么情况下会有用处? - Oliver Charlesworth
5
每当我遇到像这样的“奇怪”错误消息时,我喜欢思考它。最终,总会发现,如果某事不被允许,那么通常是因为它没有意义(就像这个例子)。 - user529758
2
@OliCharlesworth:虽然我同意这没有任何意义,而且语言不应该/不允许这样做,但我实际上找不到C99中明确禁止这种情况的任何文本。据我所知,§6.2.2、§6.2.4、§6.7.1和§6.8.5.3都没有提到对for循环的clause-1声明有任何限制。 - Adam Rosenfield
1
@OliCharlesworth 哦,实际上它在§6.8.5的顶部,我不知怎么错过了(感谢@Chux!) - Adam Rosenfield
2
for循环内部,我有一个带有数据包的循环环,索引为[0,Size-1],应该按顺序遍历该环来读取。因此,我尝试将其声明为静态变量,因为我的函数会为每个数据包调用一次。我知道将其声明在for循环外部会对我有所帮助。 - Sunil Bojanapally
显示剩余4条评论
4个回答

7

C语言不允许这样做。

C11dr 6.8.5 迭代语句 3

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

(不是static


通常情况下,代码不能从能够拥有静态迭代器中受益。


存储类说明符:

typedef
extern
static
_Thread_local
auto
register

@SunEric 这是一篇有趣的帖子。我以前从未尝试过使用“静态”迭代器。根据您上面的评论,可以轻松地绕过它(“在外部声明”)。我怀疑尝试使用“静态”迭代器的原因可能会产生意想不到的副作用(关于可重入性和其他帖子),从而排除了这种方法。祝好运。 - chux - Reinstate Monica

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循环只会被初始化一次!

// 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

实际上,这段代码能够在 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++标准允许这样做?

1

你想要达到什么目的?

如果你想在 for 循环外部访问变量 i,你需要在循环外部声明它:

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

如果您想让“for”循环仅在第一次调用函数时执行,请创建一个静态布尔变量来处理它。
static bool firstTime = true;

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

    firstTime = false;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接