C Simple return value from stdthread?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
std::thread does not give you a direct return value the way a normal function call does. A thread runs independently, so you need an explicit channel for sending the result back to the calling code.
Use std::promise and std::future
The standard library way to hand one result from a worker thread back to the caller is std::promise paired with std::future. The worker sets the value, and the main thread waits for it.
This pattern is explicit and safe. future.get() blocks until the result is ready, and it can only be consumed once.
Propagate Exceptions Cleanly
One reason promise and future are useful is that they can carry exceptions as well as values. That keeps error handling structured.
If the worker fails, the caller sees the failure when it calls get(). That is much cleaner than juggling shared error flags and mutexes.
Consider std::async When You Only Need a Result
If you do not specifically need a raw std::thread, std::async is often the simplest answer. It already returns a std::future.
This is usually easier than wiring a promise manually. The tradeoff is that std::async gives you less explicit control over thread management.
Shared State Is Possible but Easier to Get Wrong
You can also write the result into shared memory and protect it with a mutex:
This works, but it scales poorly once you need failure handling, multiple results, or more complex lifetime rules. Futures communicate intent better.
Common Pitfalls
The most common mistake is expecting std::thread itself to store the function's return value. It does not. The thread object only represents execution and joinability.
Another common error is forgetting to call join() or detach(). Destroying a joinable thread causes std::terminate, which can look unrelated to the result-passing logic.
Be careful with references as well. If the worker writes into shared state by reference, that state must stay alive until the thread is done. Otherwise you have a data race or a dangling reference bug.
Finally, if you only want asynchronous computation plus a return value, do not force std::thread into the design. std::async may be the simpler tool.
Summary
- '
std::threadhas no built-in return value channel.' - Use
std::promiseandstd::futurewhen a worker thread must return one result. - Futures can also propagate exceptions back to the caller.
- Use
std::asyncwhen you want a result without managing the thread manually. - Shared variables work, but they need careful synchronization and are easier to misuse.

