std::async used
ID |
c.correctness.std_async |
Severity |
low |
Remediation Complexity |
medium |
Remediation Risk |
medium |
Remediation Effort |
medium |
Resource |
Concurrency |
Language |
C / C++ |
Description
This calls std::async. If the returned std::future is not moved into a longer-lived object, its destructor blocks the current thread until the async task finishes — a wait that is easy to miss when reading the call site and that turns what looks like fire-and-forget concurrency into a hidden synchronization point. Use std::thread (or a thread pool) when you do not need the result back, and keep the future alive and readable when you do.
Rationale
This calls std::async. If the returned std::future is not moved into a longer-lived object, its destructor blocks the current thread until the async task finishes — a wait that is easy to miss when reading the call site and that turns what looks like fire-and-forget concurrency into a hidden synchronization point. Use std::thread (or a thread pool) when you do not need the result back, and keep the future alive and readable when you do.
The following code illustrates the pattern detected by this rule:
int compute(int n)
{
return n * n;
}
void launches_async()
{
// FLAGGED: std::async used
auto fut = std::async(std::launch::async, compute, 4);
fut.get();
}