C++ lambda lifecycle

2019-04-01 11:37发布

问题:

In the following code, what happens at runtime?

while ( ([]()->bool { return something(); })() ) {
    ...
}
  1. The lambda instance is created only once and reused in subsequent iterations.
  2. Every iteration creates a new instance, that is only used once.
  3. None of the above (please explain).

Initially it seems obvious to me that it's re-created in every iteration, but I wonder if the compiler does some kind of optimization.

回答1:

First a couple of standard quotes, with my emphasis:

[stmt.while]/1

In the while statement the substatement is executed repeatedly until the value of the condition ([stmt.select]) becomes false. The test takes place before each execution of the substatement.

[expr.prim.lambda]/2

A lambda-expression is a prvalue whose result object is called the closure object.

The above tells use that ([]()->bool { return something(); })() is evaluated before every iteration. And that the sub-expression []()->bool { return something(); } creates a prvalue. So it springs to life only during the evaluation of the full expression.

So the dry letter of the law would indicate it's a different object of the closure type that is constructed and destructed every time the condition is evaluated.

But compilers are not stupid. I believe that under the as-if rule it's more than likely to be optimized into a direct call to something(). That is because the construction and destruction of the lambda does not have observable side effects.

And if we indeed use a tool like the godbolt online compiler viewer, we see that GCC 7.2 at -O1 will call the function directly. And so does Clang 5.0, but I had to crank optimizations to -O2 for that to happen.



标签: c++ lambda