想知道为什么我不能在for
循环初始化中声明静态变量,如下所示,
for(static int i = 0;;)
使用我的C99
标准编译器编译上面的循环语句代码,我看到以下错误,
error: declaration of static variable ‘i’ in ‘for’ loop initial declaration
答案 0 :(得分:6)
C不允许
C11dr 6.8.5 迭代声明 3
“for
语句的声明部分只应声明具有存储类auto
或register
”的对象的标识符。
(不是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;
}