====== C - C++ Threads - Important Considerations - Thread function arguments are always passed by value ======
**NOTE:** Arguments are always copies into the internal storage for threads.
This means that any changes made by the thread to the arguments passed does not affect the original arguments.
* The compiler may not even allow the compilation of the program.
* To fix, ensure that arguments are passed by reference.
----
===== Example =====
#include
#include
#include
#include
void ChangeTotal(std::int& targetTotal)
{
targetTotal = 20;
std::cout << "Changing target_total to " << targetTotal << std::endl;
}
int main()
{
int total = 10;
std::thread t1(ChangeTotal, total);
t1.join();
std::cout << "Current Total is " << total << std::endl;
return 0;
}
**NOTE:** Trying to compile this will fail with a message such as the following.
The reason for this is that the arguments being passed to ChangeTotal() are not being passed by reference.
/usr/include/c++/9/thread: In instantiation of ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(int&); _Args = {int&}; = void]’:
test6.cpp:17:36: required from here
/usr/include/c++/9/thread:120:44: error: static assertion failed: std::thread arguments must be invocable after conversion to rvalues
120 | typename decay<_Args>::type...>::value,
| ^~~~~
/usr/include/c++/9/thread: In instantiation of ‘struct std::thread::_Invoker >’:
/usr/include/c++/9/thread:131:22: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(int&); _Args = {int&}; = void]’
test6.cpp:17:36: required from here
/usr/include/c++/9/thread:243:4: error: no type named ‘type’ in ‘struct std::thread::_Invoker >::__result >’
243 | _M_invoke(_Index_tuple<_Ind...>)
| ^~~~~~~~~
/usr/include/c++/9/thread:247:2: error: no type named ‘type’ in ‘struct std::thread::_Invoker >::__result >’
247 | operator()()
| ^~~~~~~~
----
==== Solution ====
Ensure that arguments are passed by reference:
#include
#include
#include
#include
void ChangeTotal(int& targetTotal)
{
targetTotal = 20;
std::cout << " Changing targetTotal to " << targetTotal << std::endl;
}
int main()
{
int total = 10;
std::thread t1(ChangeTotal, std::ref(total));
t1.join();
std::cout << "Total is " << total << std::endl;
return 0;
}
**NOTE:** The std::ref changes the parameter to be passed by reference.