Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sequence Points and Method Chaining

The following expression is often used to demonstrate undefined unspecified behaviour:

f() + g()

If f() and g() both have side effects on some shared object then the behaviour is undefined unspecified because the order of execution is unknown. f() may be evaluated before g() or vice versa.

Now I was wondering what happens when you chain member functions on an object. Let's say I have an instance of a class, the instance called obj and it has two member functions, foo() and bar() which both modify the object. The order of execution of these functions is not commutative. The effect of calling one before the other is not the same effect as calling them the other way around. Both methods return a reference to *this so that they can be chained like so:

obj.foo().bar()

But is this unspecified behaviour? I can't find anything in the standard (admittedly just scanning through) that differentiates between this expression and the expression I gave at the top of the post. Both function calls are subexpressions of the full-expression and so their order of execution is unspecified. But surely foo() must be evaluated first so that bar() knows which object to modify.

Perhaps I'm missing something obvious, but I can't see where a sequence point is created.

like image 202
Joseph Mansfield Avatar asked Apr 02 '11 12:04

Joseph Mansfield


1 Answers

f() + g()

Here the behavior is unspecified (not undefined), because the order in which each operand is evaluated (that is, each function is called) is unspecified.

 obj.foo().bar();

This is well-defined in C++.

The relevant section §1.9.17 from the C++ ISO standard reads,

When calling a function (whether or not the function is inline), there is a sequence point after the evaluation of all function arguments (if any) which takes place before execution of any expressions or statements in the function body. There is also a sequence point after the copying of a returned value and before the execution of any expressions outside the function.

Similar cases has been discussed in great detail, in these topics:

  • Undefined behavior and sequence points reloaded
  • Is this code well-defined?
like image 171
Nawaz Avatar answered Sep 27 '22 21:09

Nawaz