首先评估赋值运算符的哪一侧?
int& foo() {
printf("Foo\n");
static int a;
return a;
}
int bar() {
printf("Bar\n");
return 1;
}
void main() {
foo() = bar();
}
我不确定应该首先评估哪一个。
我在VC中尝试过首先执行bar函数。然而,在 g++ (FreeBSD) 编译器中,它首先给出 foo 函数求值。
很多有趣的问题都是从上面的问题衍生出来的,假设我有一个动态数组(std::vector),
std::vector<int> vec;
int foobar() {
vec.resize( vec.size() + 1 );
return vec.size();
}
void main() {
vec.resize( 2 );
vec[0] = foobar();
}
根据之前的结果,vc评估foobar(),然后执行向量运算符[]。在这种情况下没有问题。但是,对于 gcc,由于正在评估 vec[0],并且 foobar() 函数可能会导致更改数组的内部指针。执行 foobar() 后,vec[0] 可能会失效。
这是否意味着我们需要将代码分开
void main() {
vec.resize( 2 );
int a = foobar();
vec[0] = a;
}
int& foo() {
printf("Foo\n");
static int a;
return a;
}
int bar() {
printf("Bar\n");
return 1;
}
void main() {
foo() = bar();
}
I am not sure which one should be evaluated first.
I have tried in VC that bar function is executed first. However, in compiler by g++ (FreeBSD), it gives out foo function evaluated first.
Much interesting question is derived from the above problem, suppose I have a dynamic array (std::vector)
std::vector<int> vec;
int foobar() {
vec.resize( vec.size() + 1 );
return vec.size();
}
void main() {
vec.resize( 2 );
vec[0] = foobar();
}
Based on previous result, the vc evaluates the foobar() and then perform the vector operator[]. It is no problem in such case. However, for gcc, since the vec[0] is being evaluated and foobar() function may lead to change the internal pointer of array. The vec[0] can be invalidated after executation of foobar().
Is it meant that we need to separate the code such that
void main() {
vec.resize( 2 );
int a = foobar();
vec[0] = a;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在这种情况下,评估顺序将是未指定的。不要编写这样的代码
类似的示例
Order of evaluation would be unspecified in that case. Dont write such code
Similar example here
C++ 中控制是否定义求值顺序的概念称为序列点。
基本上,在一个序列点,可以保证该点之前的所有表达式(具有可观察到的副作用)都已被评估,并且尚未评估该点之后的任何表达式。
尽管有些人可能会感到惊讶,但赋值运算符并不是序列点。所有序列点的完整列表位于维基百科文章中。
The concept in C++ that governs whether the order of evaluation is defined is called the sequence point.
Basically, at a sequence point, it is guaranteed that all expressions prior to that point (with observable side effects) have been evaluated, and that no expressions beyond that point have been evaluated yet.
Though some might find it surprising, the assignment operator is not a sequence point. A full list of all sequence points is in the Wikipedia article.
c++17 保证
bar()
将在foo()
之前执行。在 c++17 之前,这是未指定的行为,不同的编译器会按不同的顺序进行计算。如果表达式的两侧都修改相同的内存位置,则行为未定义。
c++17 guarantees that
bar()
will be executed beforefoo()
.Before c++17 this was unspecified behaviour and different compilers would evaluate in different orders. If both sides of the expression modify the same memory location then the behaviour is undefined.
表达式的求值顺序是未指定行为。
这取决于编译器选择评估的顺序。
您应该避免编写这样的代码。
不过,如果没有副作用,那么顺序应该不重要。
如果顺序很重要,那么您的代码错误/不可移植/在不同的编译器上可能会给出不同的结果**。
Order of evaluation of an expression is Unspecified Behaviour.
It depends on the compiler which order it chooses to evaluate.
You should refrain from writing shuch codes.
Though if there is no side effect then the order shouldn't matter.
If the order matters, then your code is wrong/ Not portable/ may give different result accross different compilers**.