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

发布于 2024-10-01 15:39:04 字数 397 浏览 6 评论 0原文

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++ 标准的有效代码。

非常感谢来自该标准的报价。

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)?
};

While this compiles with the MS Visual Studio Compiler, i am not sure if this is valid code according to the C++ Standard.

Quotes from the Standard would be highly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

酒几许 2024-10-08 15:39:04

C++03/C++11 答案


不,不是。

= 的右侧,points 确实存在1,但初始化程序仅在其所有操作数都被求值后才应用。

  • 如果 points 位于命名空间范围内(因此具有静态存储持续时间并且已零初始化2),那么这是“安全的”,但您使用 < code>points[0] 将为您提供 0,而不是 QPointF(r.left() - i, r.top() - i) 再次。

  • 如果 points 具有自动存储持续时间 - 它尚未初始化,因此您对 points[0] 的使用正在尝试使用未初始化的变量,其中 point[0] 具有不确定的值...这很糟糕3

很难为此提供标准参考,只能说 8.5“Initializers” 中没有任何内容明确地使这成为可能,其他地方的规则填补了其余部分。


1 [n3290: 3.3.2/1]: 名称的声明点紧接在其完整声明符之后(子句8) 及其初始化程序之前(如果有),除非下面另有说明。 [示例:

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

此处,第二个 x 使用其自己的(不确定) 值进行初始化。 —结束示例]

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

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

C++03/C++11 answer


No, it's not.

On the right-hand side of the =, points does exist1 but the initialiser is only applied after all its operands have been evaluated.

  • If points is at namespace scope (and thus has static storage duration and has been zero-initialized2), then this is "safe" but your use of points[0] there is going to give you 0, rather than QPointF(r.left() - i, r.top() - i) again.

  • If points has automatic storage duration — it has not yet been initialised so your use of points[0] is attempting to use an uninitialised variable, where points[0] has an indeterminate value... which is bad3.

It's difficult to provide standard references for this, other than to say that there is nothing in 8.5 "Initializers" that explicitly makes this possible, and rules elsewhere fill in the rest.


1 [n3290: 3.3.2/1]: The point of declaration for a name is immediately after its complete declarator (Clause 8) and before its initializer (if any), except as noted below. [ Example:

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

Here the second x is initialized with its own (indeterminate) value. —end example ]

2 [n3290: 3.6.2/2]: Variables with static storage duration (3.7.1) or thread storage duration (3.7.2) shall be zero-initialized (8.5)
before any other initialization takes place. [..]

3 [n3290: 17.6.3.3/2]: [..] [ Note: Operations
involving indeterminate values may cause undefined behavior. —end note ]

柳絮泡泡 2024-10-08 15:39:04

来自 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)?

from 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)?
寄离 2024-10-08 15:39:04

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

否则,没有任何规定,编译器是否应该首先评估所有内容,然后分配,或者分别以何种顺序对每个元素进行评估分配。

Since there is no sequence point in the statement, the result is undefined, much like for the i=i++ example quoted at that wikipedia page.

Otherwise said, nothing specifies, whether the compiler should first evaluate everything, then assign, or do evaluate-assign for each element separately and in which order.

§对你不离不弃 2024-10-08 15:39:04

旧答案(没有抓住重点):

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

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

因此,虽然这句话不是 2003 年 C++ 标准的一部分,但我非常确定,如果这是 C++0x 的一部分,它应该可以在任何最新的编译器中工作。

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

Old Answer (misses the point):

I checked the current C++0x draft, and there i found the sentence 8.5.1.17 which says:

17 The full-expressions in an
initializer-clause are evaluated in
the order in which they appear.

So while this sentence is not part of the C++ Standard from 2003, im quite sure that this should be working in any up to date compiler, if this is part of C++0x.

Edit:
The comments made me rethink this matter. This line only ensures that the QPointF objects are created in the order in which they occur in the array initialization (relevant if the element constructors have observable side-effects). The problem is, the value of points is indeterminate during its array initialization. So there cant be a guarantee for a valid value of points[0] either, at least not if you rely on the standard.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文