为什么C编译器没有在for循环体内给出重新声明错误?

理学硕士

如果使用C语言,请编写以下代码:

for(int i = 0; i < 7; i++)
{
    // for loop Body
}

变量的范围i在for循环体内。没关系。

但是,如果我这样写:

for(int i = 0; i < 7; i++)
{
    long int i = 1; // Redeclaration of i
}

在这里,该变量i在循环体内再次声明,但它已成功编译并在C中运行。

但是,在C ++中,编译器给出“重新声明'long int i'”错误。

那么,为什么C编译器没有给出重新声明错误?它是编译器错误吗?

讲故事的人-Unslander Monica

C ++和C在这里有所区别。根据C11(n1570)§6.8.5¶5,请强调:

迭代语句是一个块,其作用域是其封闭块作用域的严格子集。循环主体还是一个块,其作用域是迭代语句作用域的严格子集

转化为for循环:

{
    declaration 
    while ( expression) {
        statement
        expression ;
    }
}

您放置在statement零件中的任何内容都可以隐藏声明中引入的任何内容。现在,C ++(17,n4659)在[stmt.for] / 1处明确声明了类似的内容但是它还继续添加:

除了init语句中声明的名称与条件中声明的名称位于相同的声明性区域外,

因此,这里的第二个i确实是尝试重新声明。上面的内容听起来令人困惑(在条件中声明了名称!?),但是此处的“条件”是这样定义的[[stmt.stmt] / 1):

condition:
    expression
    attribute-specifier-seq decl-specifier-seq declarator brace-or-equal-initializer

正是这样允许while循环这样(仅C ++):

while (T t = x) statement 

而且,您可能不会t在while循环的语句内重新声明


另外,我得出的结论也总结在[stmt.iter] / 3中(感谢@TC):

如果在子语句的最外层块中重新声明了init语句或for-range声明中引入的名称,则程序格式错误。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么编译器没有生成错误“需要左值”?

变量声明冲突的编译器错误:“与带有“ C”链接的新声明冲突”

如何解决编译器枚举重新声明冲突

为什么编译器没有优化此负载

在循环体内声明变量是否有任何缺点?

为什么编译器没有给出冲突的错误?

用公共访问编译器错误重新声明了sstream

为什么Point.Offset()在只读结构中没有给出编译器错误?

为什么声明没有给出CS0201编译器错误?

泛型类型扩展无效的重新声明编译器错误

在Node中,为什么尝试重新声明JavaScript for循环的迭代器会产生“未定义”错误而不是“重复声明”错误?

为什么编译器跳过for循环?

为什么OCaml编译器会给出有关类型推断的错误消息?

为什么这没有给出编译错误?

闭包编译器-{SyntheticVarsDeclar}:警告-重新声明的变量

为什么这没有给出编译错误

为什么在C#中未处理Delegate中的返回值时没有编译器错误抛出?

为什么循环不显示变量重新声明错误

为什么C#编译器没有抛出任何错误?

如果让我们展开,为什么没有无效的重新声明问题

在C#中为什么我可以将接口转换为任何类型而没有编译器错误

为什么DateTime const的声明会给出编译器错误而不是可选参数?

c ++:混淆为什么编译器给出未在此范围内声明的错误

为什么在编写一个不返回任何内容且没有副作用的函数时,C 编译器不会给出警告?

为什么即使函数没有在 main 之前声明,这个在线编译器也允许我编译代码?

为什么 Kotlin 编译器在有效的 IF 语句中给出错误?

为什么我的程序没有显示任何输出?0 错误,0 警告但没有输出?我正在使用 Dev C++ 编译器

为什么在 C 中重新声明函数是合法的?

为什么全局变量没有在没有将其重新声明为局部变量的函数内更新?