显然,您可以在for循环中放置变量声明:
for (int i = 0; ...
而且我注意到你可以在if和switch语句中做同样的事情:
if ((int i = f()) != 0) ... switch (int ch = stream.get()) ...
但是当我尝试在while循环中执行相同的操作时:
while ((int ch = stream.get()) != -1) ...
编译器(VC++ 9.0)根本不喜欢它.
这是合规行为吗?有原因吗?
编辑:我发现我可以这样做:
while (int ch = stream.get() != -1) ...
但由于优先规则,这被解释为:
while (int ch = (stream.get() != -1)) ...
这不是我想要的.
'03标准中条件的语法定义如下:
condition: expression type-specifier-seq declarator = assignment-expression
因此,上述内容仅允许以下条件:
if ( i && j && k ) {} if ( (i = j) ==0 ) {} if ( int i = j ) {}
该标准允许条件声明一个变量,但是,他们通过添加一个名为'condition'的新语法规则来实现,该规则可以是一个表达式,也可以是一个带有初始化器的声明符.其结果是,仅仅因为你是在一个条件下if
,for
,while
,或switch
并不意味着你可以声明一个表达式中的变量.
问题是,标准允许你在括号内声明.你想要做的是将声明作为表达的一部分,这是标准不允许你做的事情.
while()可以有两种语法之一:while(
当你写作
while(int i = 1) { }
,那很好."int i = 1"是一个声明.但是,你想要的是什么
while ( (int i = 1) + 3) { }
这是一种非常不同的动物.你想在while()中有一个表达式,其中表达式的一个术语是声明.现在,声明是一种陈述,因此不能成为表达的一部分.这就是为什么你需要做的事情无法完成的原因.
(在写完整个咆哮之后,我注意到另外两个人写了同样的东西.哦,嗯,越多越好.)
这似乎不是合规行为.标准的第6.5.1.2部分规定:
当while语句的条件是声明时,声明的变量的范围从其声明点(3.3.1)延伸到while语句的结尾.一段时间的表格声明
而(T t = x)陈述
相当于
label: { //start of condition scope T t = x; if (t) { statement goto label; } }
因此,在您的示例中,ch应该在循环的范围内声明并正常工作(通过每次循环迭代重新创建它).观察到的行为的原因很可能是由于编译器没有正确确定变量的范围,然后多次声明它.