In f (x), x can be evaluated to f?

I have a C ++ program. This program does something like this:

struct MyT {void memfunc(std::unique_ptr<MyT> arg);}; std::unique_ptr<MyT> obj = /* some init */; obj->memfunc(std::move(obj)); 

Is it guaranteed that I can end the member function call on nullptr ?
Standard quotation marks apply.
I know that the order in which the arguments are evaluated does not matter, but I do not remember that the sequence is a wrt function object being called.

+52
c ++ c ++ 11
May 16 '14 at 19:57
source share
2 answers

Pre-C ++ 17, this behavior is undefined:

Here's a quote that proves that the entire score needed to call a function and its associated side effects is sequenced before the function is called.
In addition, all other estimates that do not have a specific sequence are indefinitely sequenced. This does not impose any restrictions on the ordering of the subexpressions evaluated, although with respect to each other, they remain inconsistent with respect to each other.

1.9 Execution of the program ยง 15

Except where noted, evaluations of the operands of individual operators and subexpressions of individual expressions are not affected. [...]
The calculation of the values โ€‹โ€‹of the operands of the operator is sequenced before calculating the value of the result of the operator. If the side effect of the scalar object does not affect any other effect on the same scalar object or the calculation of the value using the value of the same scalar object, the behavior is undefined.
When a function is called (regardless of whether the function is built-in), each value calculation and side effect associated with any argument expression, or with the postfix expression representing the called function, are sequenced before each expression or statement in the body of the called function.
[Note. Value calculations and side effects associated with different argument expressions have no meaning. -end note]
Each estimate in the calling function (including other function calls), which otherwise is not secreted separately before or after the body of the called function is executed, is indefinitely ordered with respect to the execution of the called function . 9 Several contexts in C ++ cause an evaluation of a function call, even if the syntax of the corresponding functions is not displayed in the translation block. . [...]
The sequence constraints for executing the called function (as described above) are function call functions that are evaluated, regardless of the syntax of the expression that calls the function.

Other relevant quotes relate to std::move

template typename remove_reference :: type && & move (T & t) noexcept;
Returns: static_cast <typename remove_reference :: type &> (t).

And std::unique_ptr<T>.operator->() :

20.7.1.2.4 unique_ptr observers

pointer operator โ†’ () const noexcept;
Requires: get ()! = Nullptr.
Returns: get ().

memfunc gets its argument by value, so we have 3 calls:
a) obj->memfunc b) std::move(obj)
c) the constructor for moving the argument passed.
Since b) does not change anything, we can ignore it for the argument:

a and c are indefinitely sequenced, so either they can be in front of another.
If the first one happens, everything is fine; c changing obj doesn't matter.
If c occurs first, a is evaluated with zero obj , violating the precondition, so we have UB.

So this is undefined Behavior, because one of the allowed orders has undefined behavior.

Post-C ++ 17, it is defined correctly:

8.2.2 Function call [expr.call]

1 A function call is a postfix expression, followed by parentheses containing possibly empty comma-separated lists of initializers that make up the arguments to the function. [...]
[...]
5 A post-simulation is sequenced before each expression in the expression list and any default argument. [...]
[...]

+19
May 16 '14 at 20:08
source share

Yes , an estimate of x can occur before, after, or during an estimate of f (they are not subject to sequence).

[Note. The evaluations of postfix expressions and argument expressions are not affected relative to each other. All side effects of evaluations of the expression of arguments are sequenced before the function (see 1.9). - final note]

(C ++ 11, ยง 5.2.2 / 8)

+18
May 16 '14 at 20:04
source share



All Articles