问题描述
下面是示例代码:
X * makeX(int index){return new X(index); }
struct Tmp {
mutable int count;
Tmp():count(0){}
const X ** getX()const {
static const X * x [] = {makeX(count ++),makeX ;
return x;
}
};
这会在静态数组构造中报告CLang build 500上的未定义行为。
为了简化这篇文章,计数不是静态的,但它不会改变任何东西。我收到的错误如下:
更新2
$ b
所以经过一些研究,我意识到这实际上是定义明确的,虽然评估顺序是未指定。这是一个非常有趣的把这些组合在一起,虽然有一个更一般的问题覆盖这个在序列点内多次修改变量,我们可以看到,通过查看相关中的部分是 段 的 5 段 >
通过表达式的评估。此外,仅访问先前值以确定要存储的值。对于一个完整表达式的子表达式的每个允许排序,应满足本段的要求;
1.9
段的段落 p> ,我们可以从code> 8.5.4 的 段落说:
Here's the sample code:
X * makeX(int index) { return new X(index); }
struct Tmp {
mutable int count;
Tmp() : count(0) {}
const X ** getX() const {
static const X* x[] = { makeX(count++), makeX(count++) };
return x;
}
};
This reports Undefined Behavior on CLang build 500 in the static array construction.For sake of simplification for this post, the count is not static, but it does not change anything. The error I am receiving is as follows:
Update 2
So after some research I realized this was actually well defined although the evaluation order is unspecified. It was a pretty interesting putting the pieces together and although there is a more general question covering this for the C++11 case there was not a general question covering the pre C++11 case so I ended up creating a self answer question, Are multiple mutations of the same variable within initializer lists undefined behavior pre C++11 that covers all the details.
Basically, the instinct when seeing makeX(count++), makeX(count++)
is to see the whole thing as a full-expression but it is not and therefore each intializer has a sequence point.
Update
As James points out it may not be undefined pre-C++11, which would seem to rely on interpreting the initialization of each element as a full expression but it is not clear you can definitely make that claim.
Original
Pre-C++11 it is undefined behavior to modify a variable more than once within a sequence point, we can see that by looking at the relevant section in an older draft standard would be section 5
Expressions paragraph 4 which says (emphasis mine):
In the C++11 draft standard this changes and to the following wording from section 1.9
Program execution paragraph 15 says (emphasis mine):
and we can see that for initializer lists from section 8.5.4
List-initialization paragraph 4 says:
这篇关于为什么这个未定义的行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!