后自增运算符的求值按什么顺序发生?

发布于 2024-08-27 03:42:48 字数 353 浏览 4 评论 0原文

鉴于

std::vector<CMyClass> objects;
CMyClass list[MAX_OBJECT_COUNT];

这样做明智吗?

for(unsigned int i = 0; i < objects.size(); list[i] = objects.at(i++));

或者我应该将循环扩展到此?

for(unsigned int i = 0; i < objects.size(); i++)
{
  list[i] = objects.at(i);
}

Given

std::vector<CMyClass> objects;
CMyClass list[MAX_OBJECT_COUNT];

Is it wise to do this?

for(unsigned int i = 0; i < objects.size(); list[i] = objects.at(i++));

Or should I expand my loop to this?

for(unsigned int i = 0; i < objects.size(); i++)
{
  list[i] = objects.at(i);
}

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

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

发布评论

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

评论(4

迷离° 2024-09-03 03:42:48

前者是未定义的行为。未指定在对 objects.at 的函数调用之前还是之后计算 list[i](为赋值的左值提供左值)。

因此,表达式的各个部分都有一个合法的顺序,其中 i 被访问(在 list[i] 中)并单独修改(在 i++< /code>),没有中间序列点。

这正是 C++ 标准中未定义行为的条件 - 是否存在这样的合法顺序。 IIRC C 标准的表达方式略有不同,但效果相同。

如果有疑问,请勿编写使用增量运算符的表达式,并且在表达式中的其他任何位置也使用相同的值。您可以使用逗号运算符(i++, i++ 很好)和条件运算符(i ? i++ : i-- 很好)来完成此操作,因为它们在他们,但这很少值得。 ||&& 同样,以及类似 p != end_p && *(p++) = some; 并非完全难以置信。任何其他用途,如果你盯着它看足够长的时间,你通常可以找出一个使事情变得混乱的评估顺序。

这还不包括复杂的 for 表达式和带有空体的 for 循环的可理解性。

The former is undefined behavior. It's not specified whether list[i] is evaluated (to provide an lvalue for the lhs of the assignment) before or after the function call to objects.at.

Hence there is a legal ordering of the various parts of the expression, in which i is accessed (in list[i]) and separately modified (in i++), without an intervening sequence point.

This is precisely the condition for undefined behavior in the C++ standard - whether such a legal ordering exists. IIRC the C standard expresses it slightly differently but with the same effect.

If in doubt, don't write an expression which uses an increment operator, and also uses the same value anywhere else in the expression. You can do it with the comma operator (i++, i++ is fine) and the conditional operator (i ? i++ : i-- is fine) because they have sequence points in them, but it's rarely worth it. || and && likewise, and something like p != end_p && *(p++) = something; isn't totally implausible. Any other use, and if you stare at it long enough you can usually work out an order of evaluation that messes things up.

That's aside from the comprehensibility of complicated for expressions and for loops with empty bodies.

鹊巢 2024-09-03 03:42:48

如有疑问,请选择更容易理解的形式(展开循环)。

(我认为 list[i] =objects.at(i++) 会导致未定义的行为。)

When in doubt, prefer the form which is easier to understand (expand the loop).

(And I think list[i] = objects.at(i++) leads to undefined behavior.)

不必在意 2024-09-03 03:42:48

在与 i++ 相同的表达式中引用 i 可能是未定义的行为。但既然看起来你正在使用容器,你可以写......

list = objects;                               // if they're the same type
list.assign(objects.begin(), objects.end());  // if not

Referencing i in the same expression as i++ is probably undefined behavior. But since it looks like you're using containers, could you maybe write...

list = objects;                               // if they're the same type
list.assign(objects.begin(), objects.end());  // if not
无所谓啦 2024-09-03 03:42:48

正如已经说过的,在使用的同一表达式中后递增变量会产生未定义的行为。
但是,如果您希望保持紧凑的形式,您可以引入一个序列点并继续

for(unsigned int i = 0; i < objects.size(); list[i] = objects.at(i), i++);

As it has been said already, post-incrementing a variable in the same expression it is used yields undefined behaviour.
However, if you wish to keep the compact form, you could introduce a sequence point and go for

for(unsigned int i = 0; i < objects.size(); list[i] = objects.at(i), i++);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文