So I was trying to get my feet wet with asio library. But am baffled by the following lambda capture mystery.
#include <iostream>
#include <asio/include/asio.hpp>
void handler1( const asio::error_code& ec, asio::steady_timer& t, int count ) {
if( count < 5 ) {
std::cout << "I have waited " << count << " seconds\n";
t.expires_at( t.expiry() + asio::chrono::seconds( 1 ) );
// auto next_count = count + 1;
t.async_wait( [&t, &count]( const asio::error_code& ec ) {
handler1( ec, t, count + 1 );
});
}
}
int main(int argc, char *argv[])
{
asio::io_context io_context;
asio::steady_timer t ( io_context, asio::chrono::seconds( 1 ) );
t.async_wait( [&t]( const asio::error_code& ec ) {
handler1( ec, t, 0 );
}
);
io_context.run();
return 0;
}
Problem happens on the &count lambda capture in the handler1 function. This code will produce the following on my Mac:
(Apple Clang++ 15.0.0)
I have waited 0 seconds
I have waited 2 seconds
I have waited 2 seconds
... ...
(g++ 13.2.0)
I have waited 0 seconds
I have waited 1 seconds
I have waited 1 seconds
... ...
If the &count capture is changed to count, which is capture by copy, it produces expected behavior
(g++ 13.2.0)
I have waited 0 seconds
I have waited 1 seconds
I have waited 2 seconds
I have waited 3 seconds
... ...
So what is going on. I am pretty sure the function handler1 captures count by copy, so I don't think there will be any difference between capturing the count by reference or value in the lambda capture.