首先评估赋值运算符的哪一侧?

发布于 2024-12-18 11:57:20 字数 760 浏览 3 评论 0原文

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 技术交流群。

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

发布评论

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

评论(4

忱杏 2024-12-25 11:57:20

在这种情况下,评估顺序将是未指定的。不要编写这样的代码

类似的示例

Order of evaluation would be unspecified in that case. Dont write such code

Similar example here

靑春怀旧 2024-12-25 11:57:20

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.

泪眸﹌ 2024-12-25 11:57:20

c++17 保证 bar()将在 foo() 之前执行。

在 c++17 之前,这是未指定的行为,不同的编译器会按不同的顺序进行计算。如果表达式的两侧都修改相同的内存位置,则行为未定义。

c++17 guarantees that bar() will be executed before foo().

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.

逆光飞翔i 2024-12-25 11:57:20

表达式的求值顺序是未指定行为
这取决于编译器选择评估的顺序。

您应该避免编写这样的代码。
不过,如果没有副作用,那么顺序应该不重要。

如果顺序很重要,那么您的代码错误/不可移植/在不同的编译器上可能会给出不同的结果**。

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**.

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