I have program that receives callback calls from a library when messages are received. The callbacks’ signature is void on_message(const MyLargeObject &my_large_object);
My code for reacting to some of the messages is more complex than what I want to run directly in the callbacks. Because of that, I am launching an asynchronous task (std::async) to do the actual processing.
Currently, the asynchronous tasks’ signature is void on_message_async_task(MyLargeObject my_large_object);
. My reasoning says that I should pass the argument to the async task as a copy because I see no guarantee that the original object lives until the task is finished. Static code analysis is, however, saying that I should use const reference instead to avoid expensive copying. Is that false positive or am I missing something here?
10
Task functor accepting an object by reference seems like a reasonable suggestion. Note that it does not imply that task’s shared state should store reference to the object from library callback. Task should create a copy so it survives long enough, however functor should accept a reference to avoid yet another copy when it is invoked.
#include <future>
#include <iostream>
struct Object
{
Object()
{ ::std::cout << static_cast<void *>(this) << " Object{}n"; }
Object(Object const & object)
{ ::std::cout << static_cast<void *>(this) << " Object{copy}" << static_cast<void const *>(&object) <<"n"; }
~Object()
{ ::std::cout << static_cast<void *>(this) << " ~Objectn"; }
};
void ByRef(Object const & object)
{ ::std::cout << static_cast<void const *>(&object) << " ByRefn"; }
void ByCopy(Object const object)
{ ::std::cout << static_cast<void const *>(&object) << " ByCopyn"; }
void Callback(Object const & object)
{
::std::cout << "ByRef Startn";
::std::async(::std::launch::async, ByRef, object).get();
::std::cout << "ByCopy Startn";
::std::async(::std::launch::async, ByCopy, object).get();
}
int main()
{
Object object{};
Callback(object);
::std::cout << "Donen";
return 0;
}
online compiler
0x7ffe6a71789f Object{}
ByRef Start
0x14e6308 Object{copy}0x7ffe6a71789f
0x14e6308 ByRef
0x14e6308 ~Object
ByCopy Start
0x14e6308 Object{copy}0x7ffe6a71789f
0x7149b1bfecc8 Object{copy}0x14e6308
0x7149b1bfecc8 ByCopy
0x7149b1bfecc8 ~Object
0x14e6308 ~Object
Done
0x7ffe6a71789f ~Object