(C / C ++)数组初始化可以引用自身吗?

时间:2012-02-27 15:47:14

标签: c++

我想知道以下形式的初始化:

int  array[] = {
v - 1,
array[0] + 1
} ;

在第二个元素的初始化中,使用第一个元素的值,但尚未初始化整个数组。这恰好用g ++编译,但我不确定这是否实际上是可移植的和定义良好的构造?

4 个答案:

答案 0 :(得分:16)

见3.3.2声明要点:

  

名称的声明点在其完整的声明者(第8条)之后及之前   初始化程序(如果有),除非如下所述。 [例如:

int x = 12;
{ int x = x; }
  

这里第二个x用它自己的(不确定的)值初始化。 - 例子]

因此,您正确引用数组,其名称在=之后已知。

然后,8.5.1聚合:

  

聚合是数组或类[...]

     

17:初始化子句中的完整表达式按它们出现的顺序进行评估。

但是,我没有看到什么时候将评估值实际写入数组,因此我不会依赖于此,甚至会将代码声明为未定义好。

答案 1 :(得分:13)

据我所知,这是定义良好。标准(C ++ 11,8.5.1 / 17)指定 initializer-clause 中的完整表达式按照它们出现的顺序进行评估“ ,但是在评估下一个元素之前,我看不到任何需要从 initializer-clause 的结果初始化每个聚合元素的内容。

答案 2 :(得分:1)

  

(C / C ++)数组初始化是否可以自行引用?

这也是有效的C代码。

C有一些相应的段落(强调我的)。

  

(C99,6.2.1p7)“结构,联合和枚举标记的范围在声明标记的类型说明符中标记出现之后开始。每个枚举常量的范围都在出现之后开始。它在枚举器列表中定义枚举器。任何其他标识符的范围都在其声明者完成之后开始。

答案 3 :(得分:0)

我认为这是由http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1343处理的。最初我的报告只是关于命名空间范围对象的非类初始化程序(参见When exactly is an initializer temporary destroyed?),但是如果它们是非类的,那么聚合元素也存在问题。正如最近的附加说明所解释的那样,即使它是一个类对象,即使它似乎也存在于整个聚合初始化中,因为这样就不会发生构造函数调用会扩大初始化程序的完整表达式。

如果代替int你将使用一个类,并且初始化将是一个构造函数调用,那么该构造函数调用将是包含aggregate-ininitializer元素的相同完整表达式的一部分,因此这里订单没问题,你的代码定义明确。