Given the following program:
#include <iostream>
#include <memory>
using namespace std;
int main() {
std::shared_ptr<int> i(new int(42));
cout << i.use_count() << endl;
auto fn = [=](){i; cout << 42 << endl;};
cout << i.use_count() << endl;
return 0;
}
When does the compiler decide which objects it will capture?
The shared_ptr i
is never used in the lambda expression. So in a normal function I would assume that the optimizer will remove this nop statement.
But if it is removed the compiler could think that i
needs not to be captured.
So with gcc this program will always produce 1,2 as an output.
But is this guaranteed by the standard?
With a default-capture of
[=]
, any local variable is captured if it's odr-used within the lambda. The definition of odr-used is:Here,
i
is an evaluated expression, and isn't a constant; so it isodr-used
and therefore is captured; whether or not evaluating the expression has any effect.tl;dr yes.
If we go to cppreference page on lambda function they have the following explanation:
and further says:
The reference section for odr-used says:
The exceptions do not apply to
i
soi
will be captured.Which agrees with the draft C++11 standard section
5.1.2
Lambda expressions paragraph 11 which says: