数组初始化,引用前一个元素好吗?

时间:2010-11-06 19:30:29

标签: c++ arrays initialization standards

const QPointF points[] =
{
    QPointF(r.left() - i, r.top() - i),
    QPointF(r.right() + i, r.top() - i),
    QPointF(r.right() + i, r.bottom() + i),
    QPointF(r.left() - i, r.bottom() + i),
    points[0] // is this line valid (according to the C++ standard)?
};

虽然这与MS Visual Studio编译器一起编译,但我不确定这是否是符合C ++标准的有效代码。

标准中的引言将非常受欢迎。

4 个答案:

答案 0 :(得分:3)

C ++ 03 / C ++ 11回答


不,不是。

=的右侧,points确实存在 1 ,但初始化程序仅在评估了所有操作数之后应用。

  • 如果points位于命名空间范围内(因此具有静态存储持续时间且已初始化为零 2 ),那么这是“安全”但您使用{ {1}}我们会再次给你points[0],而不是0

  • 如果QPointF(r.left() - i, r.top() - i)具有自动存储持续时间 - 它尚未初始化,那么您使用points正在尝试使用未初始化的变量,其中points[0]具有不确定的值......这是不好的 3

很难为此提供标准参考,除了说points[0]中没有任何内容可以明确地使这成为可能,而其他地方的规则则填补其余内容。


  

1 8.5 "Initializers" 名称的声明点紧跟在其完整声明者(第8条)之后和其初始化者之前(如果有的话),除了如下所述。 [示例:

[n3290: 3.3.2/1]:
     

此处,第二个int x = 12; { int x = x; } 使用自己的(不确定)值进行初始化。 -end example ]

     

2 x具有静态存储持续时间(3.7.1)或线程存储持续时间(3.7.2)的变量应为零初始化(8.5)   在进行任何其他初始化之前。 [..]

     

3 [n3290: 3.6.2/2]: [..] [注意:操作   涉及不确定的值可能会导致未定义的行为。 -end note ]

答案 1 :(得分:2)

来自http://www.comeaucomputing.com/pcgi-bin/compiler.cgi

Copyright 1988-2008 Comeau Computing.  All rights reserved.
MODE:strict errors C++ C++0x_extensions

"ComeauTest.c", line 8: warning: variable "points" is used before its value is set
      points[0] // is this line valid (according to the C++ standard)?

答案 2 :(得分:0)

由于语句中没有sequence point,因此结果未定义,就像维基百科页面引用的i=i++示例一样。

否则说,没有任何说明,编译器是应该首先评估所有内容,然后分别为每个元素分配,或者为每个元素分别评估和分配。

答案 3 :(得分:-2)

旧答案(忽略了这一点):

我检查了当前的C ++ 0x草案,在那里我找到了句子8.5.1.17,其中说:

  

17中的完整表达    initializer-clause 在中进行评估   它们出现的顺序。

因此虽然这句话不是2003年C ++标准的一部分,但我很确定这应该适用于任何最新的编译器,如果这是C ++ 0x的一部分。

修改
这些评论使我重新思考这件事。此行仅确保QPointF对象按照它们在数组初始化中出现的顺序创建(如果元素构造函数具有可观察的副作用,则相关)。问题是,points的值在数组初始化期间是不确定的。因此,无法保证points[0]的有效值,至少在您依赖标准时是这样。