后自增运算符的求值按什么顺序发生?
鉴于
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
前者是未定义的行为。未指定在对
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 toobjects.at
.Hence there is a legal ordering of the various parts of the expression, in which
i
is accessed (inlist[i]
) and separately modified (ini++
), 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 likep != 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 andfor
loops with empty bodies.如有疑问,请选择更容易理解的形式(展开循环)。
(我认为
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.)在与
i++
相同的表达式中引用i
可能是未定义的行为。但既然看起来你正在使用容器,你可以写......Referencing
i
in the same expression asi++
is probably undefined behavior. But since it looks like you're using containers, could you maybe write...正如已经说过的,在使用的同一表达式中后递增变量会产生未定义的行为。
但是,如果您希望保持紧凑的形式,您可以引入一个序列点并继续
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