c:c_threads:important_considerations:thread_function_arguments_are_always_passed_by_value
Table of Contents
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 <iostream> #include <string> #include <thread> #include <functional> 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&}; <template-parameter-1-3> = 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<std::tuple<void (*)(int&), int> >’: /usr/include/c++/9/thread:131:22: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(int&); _Args = {int&}; <template-parameter-1-3> = 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<std::tuple<void (*)(int&), int> >::__result<std::tuple<void (*)(int&), int> >’ 243 | _M_invoke(_Index_tuple<_Ind...>) | ^~~~~~~~~ /usr/include/c++/9/thread:247:2: error: no type named ‘type’ in ‘struct std::thread::_Invoker<std::tuple<void (*)(int&), int> >::__result<std::tuple<void (*)(int&), int> >’ 247 | operator()() | ^~~~~~~~
Solution
Ensure that arguments are passed by reference:
#include <iostream> #include <string> #include <thread> #include <functional> 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.
c/c_threads/important_considerations/thread_function_arguments_are_always_passed_by_value.txt · Last modified: 2021/03/05 10:49 by peter