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

时间:2017-07-27 17:38:53

标签: c++ c const lifetime object-lifetime

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

示例代码:

for(int i = 0; i < 10; ++i)
{
  const int constant = i;
}

4 个答案:

答案 0 :(得分:6)

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

*您无法真正重新初始化&#34;在C ++中,初始化只在对象的生命周期中发生一次

答案 1 :(得分:3)

如果要遵循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;
}

循环体是一个块。变量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;
}

它的输出是

constant = 0
constant = 0
constant = 0
constant = 0
constant = 0
constant = 0
constant = 0
constant = 0
constant = 0
constant = 0

答案 2 :(得分:2)

你实际上并没有在这里重新初始化。您每次循环都会创建一个新变量。

constant是循环内部块的本地。当块在给定的迭代上完成并且控制返回到for时,constant超出范围,因此不再存在。当for开始循环的下一次迭代时,会创建并初始化constant的新实例。

答案 3 :(得分:1)

这个变量在每次迭代时被初始化和销毁​​,因为它是本地到循环。