Say I have the following call:
o->f( x, y )
Is o
guaranteed to be evaluated before x
and y
, or is o
considered to be an ordinary parameter and thus evaluated at some undefined point along with x
and y
, before control passes into f
?
Basically, are the values of this
and c
in C::Foo
going to be well defined in either Func1
or Func2
, or is this the classic Foo( i++, i++, i++ )
pro开发者_StackOverflowblem in disguise?
class C
{
public:
void Foo( C *c );
};
void Func1( C *c )
{
c->foo( c++ );
}
void Func2( C *c )
{
(c++)->foo( c );
}
Edit: does anything change if c
is not a pointer but some object that provides overloaded ++
and ->
operators?
The postfix expression that selects the function (c->foo
or (c++)->foo
) and the function arguments are all evaluated before the function is called and there is a sequence point after the evaluation of all parameters and immediately before the function body is entered so you would in theory be guaranteed the side effects would be completed in both cases before the body of foo
is entered.
However, there is no sequence point between the evaluation of any of the function parameters or the postfix expression which designates the this
object and the function to be called so in both cases it is undefined behaviour because evaluation of the lone c
- whether used for the "this
" parameter or the normal function parameter - is not "protected" by a sequence point from the result of the side effect of c++
for the other parameter.
5.2.2 [expr.call]:
The order of evaluation of arguments is unspecified. All side effects of argument expression evaluations take effect before the function is entered. The order of evaluation of the postfix expression and the argument expression list is unspecified.
精彩评论