想知道为什么不能像下面这样在for
循环初始化中声明静态变量:
for(static int i = 0;;)
使用我的
C99
标准编译器编译上述循环语句代码时,我看到以下错误:error: declaration of static variable ‘i’ in ‘for’ loop initial declaration
C语言不允许这样做。
C11dr 6.8.5 迭代语句 3
“for
语句的声明部分只能声明具有存储类auto
或register
的标识符。”
(不是static
)
通常情况下,代码不能从能够拥有静态迭代器中受益。
存储类说明符:
typedef
extern
static
_Thread_local
auto
register
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;;) {
// ...
}
实际上,这段代码能够在 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
你想要达到什么目的?
如果你想在 for
循环外部访问变量 i
,你需要在循环外部声明它:
int i;
for(i = 0; ; )
{
…
}
printf("%d\n", i);
static bool firstTime = true;
if(firstTime)
{
for(int i = 0; ; )
{
…
}
firstTime = false;
}
for
循环的clause-1
声明有任何限制。 - Adam Rosenfieldfor
循环内部,我有一个带有数据包的循环环,索引为[0,Size-1]
,应该按顺序遍历该环来读取。因此,我尝试将其声明为静态变量,因为我的函数会为每个数据包调用一次。我知道将其声明在for
循环外部会对我有所帮助。 - Sunil Bojanapally