====== 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.