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 ++标准的有效代码。
标准中的引言将非常受欢迎。
答案 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]
的有效值,至少在您依赖标准时是这样。