In what order does evaluation of post-increment operator happen?

后端 未结 4 1495
萌比男神i
萌比男神i 2021-01-20 08:36

Given

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

Is it wise to do this?

for(unsigned int i = 0;          


        
相关标签:
4条回答
  • 2021-01-20 08:52

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

    0 讨论(0)
  • 2021-01-20 08:54

    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.

    0 讨论(0)
  • 2021-01-20 09:10

    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
    
    0 讨论(0)
  • 2021-01-20 09:10

    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++);
    
    0 讨论(0)
提交回复
热议问题