cplusplus / draft

C++ standards drafts
http://www.open-std.org/jtc1/sc22/wg21/
5.69k stars 748 forks source link

[expr.call] The value computation of a function call and the evaluations of expressions within the function body are not specified #5476

Open xmh0511 opened 2 years ago

xmh0511 commented 2 years ago
bool fun(){
  int a = 0, b, c  = 0;
  b =  ++a;
  return c = a++;
}
bool r = !fun();

The current wording does not seem to specify the value computation of the function call expression fun() and the evaluation of expressions within the function body(e.g. the side effect of expression a). Every evaluation of the expressions before return statement ought to be guaranteed to be sequenced before the value computation of the function call. There is no explicit wording for this point. The relevant wording about the sequence for function call are defined in [expr.call] and [basic.exec] [expr.call] p8

The postfix-expression is sequenced before each expression in the expression-list and any default argument. The initialization of a parameter, including every associated value computation and side effect, is indeterminately sequenced with respect to that of any other parameter.

[intro.execution] p11

When invoking a function (whether or not the function is inline), every argument expression and the postfix expression designating the called function are sequenced before every expression or statement in the body of the called function. For each function invocation or evaluation of an await-expression F, each evaluation that does not occur within F but is evaluated on the same thread and as part of the same signal handler (if any) is either sequenced before all evaluations that occur within F or sequenced after all evaluations that occur within F;39 if F invokes or resumes a coroutine ([expr.await]), only evaluations subsequent to the previous suspension (if any) and prior to the next suspension (if any) are considered to occur within F.

Neither of them can clarify the above issue.

xmh0511 commented 2 years ago

Maybe, we could change [stmt.return] p5 to clarify this issue, that is:

The value computation or the copy-initialization of the returned reference of the call is considered part of the full-expression established by the operand of the return statement, which is sequenced before the destruction of temporaries at the end of the full-expression, which, in turn, is sequenced before the destruction of local variables ([stmt.jump]) of the block enclosing the return statement.

If we consider any evaluation of a prvalue(i.e. initialize result object or compute the value for operation) is a kind of value computation, see https://github.com/cplusplus/draft/issues/5477