为什么我可以在循环内重新初始化常量?

use*_*454 3 c c++ const lifetime object-lifetime

编译器不会为以下代码抛出任何警告或错误.const限定符的含义是否被滥用?显然,我不能在同一循环迭代中重新分配它,但它确实似乎在每次迭代后重新分配它.

示例代码:

for(int i = 0; i < 10; ++i)
{
  const int constant = i;
}
Run Code Online (Sandbox Code Playgroud)

jua*_*nza 6

你没有重新初始化它,你只是在每次循环迭代*中初始化它.在每个循环迭代中正式创建和销毁一个新的存在,尽管编译器可以做任何想做的事情,只要它看起来像那样.int


*您无法在C++中"重新初始化"事物,初始化仅在对象的生命周期中发生一次


Vla*_*cow 5

如果要遵循C标准,那么(6.2.4对象的存储期限)

1 对象的存储期限决定了其生存期。 有四个存储期限:静态,线程,自动和已分配。分配的存储在7.22.3中描述。

5 声明没有链接且没有存储类说明符static的对象的对象具有自动存储期限,某些复合文字也具有自动存储期限。尝试从与对象关联的线程之外的线程间接访问具有自动存储持续时间的对象的结果是实现定义的。

6对于这种没有可变长度数组类型的对象,其生存期从进入与之关联的块开始,一直到该块的执行以任何方式结束。(进入封闭的块或调用函数会挂起,但不会结束当前块的执行。)如果递归地输入该块,则每次都会创建该对象的新实例。对象的初始值不确定。如果为该对象指定了初始化,则每次在执行该块时到达声明或复合文字时都将执行该初始化;否则,每次到达声明时,该值将变得不确定

最后(6.8.5迭代语句)

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

因此在此循环语句中

for(int i = 0; i < 10; ++i)
{
    const int constant = i;
}
Run Code Online (Sandbox Code Playgroud)

循环的主体是一个块。该变量constant具有自动存储期限。每次递归执行该块时,都会创建该变量的新实例。

在C ++中,您可以添加存储类说明符static。在这种情况下,该变量实际上仅会初始化一次,因为它具有静态存储持续时间(在C中,您可能不会执行相同的操作,因为该变量必须由一个常量表达式初始化)。

这是一个示范节目

#include <iostream>

int main() 
{
    for ( int i = 0; i < 10; ++i )
    {
        static const int constant = i;
        std::cout << "constant = " << constant << std::endl; 
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它的输出是

constant = 0
constant = 0
constant = 0
constant = 0
constant = 0
constant = 0
constant = 0
constant = 0
constant = 0
constant = 0
Run Code Online (Sandbox Code Playgroud)