在do-while 循环体中声明的变量超出其条件表达式的范围是有充分理由的:减少由于未初始化变量而处理未定义行为的可能性。
考虑您的示例代码段的细微变化:
do {
if (not_ready_yet()) {
sleep(1);
continue;
}
Type value(GetCurrentValue());
Process(value);
} while (condition(value)); // error
如果 C++ 允许在循环条件中使用循环范围的变量,这种跳转(通过continue
)到条件表达式将产生未定义的行为,因为它访问了一个未初始化的变量(value
在我们的示例中)。
有了它的样子,就不会犯这样的错误。
由于 C++ 允许以多种方式使用未初始化的变量,例如
for (int j; j<10; ++j)
do_something();
或者
int foo(int i) {
if (i > 10)
goto end;
int x = 23;
end:
return x;
}
要不就
int foo(int i)
{
int k;
return k + i + 1;
}
首先,上述原因可能不是驱动 do-while 循环的设计者的原因。
以当前方式使用它可以简化编译器(和语言),因为作为 do-while 循环体的复合语句具有与所有其他复合语句完全相同的范围规则。
对于必须处理有限资源的早期 C 编译器来说,这可能是一个强有力的论据。由于 C++ 是基于 C 构建的,因此有强烈的动机不改变这些基本的设计决策。
看看理论上的替代方案,除了改变范围规则只是为了做,像这样的东西可能是一个选择:
do (Type value(GetCurrentValue())) {
Process(value);
} while (condition(value));
但是,这可能会使人们对是否value
每次迭代都重新初始化感到困惑。
不过,使用当前的语言,像这样重写它并不算太糟糕:
for (;;) {
Type value(GetCurrentValue());
Process(value);
if (!condition(value))
break;
}
只比原始代码段多一行。并且打字少于:
do {
Type value(GetCurrentValue());
Process(value);
if (!condition(value))
break;
} while (true);