Undefined behavior is behavior for which the C++ standard imposes no requirements. Once a program has it, the behavior of the whole application is unconstrained. section 5.1.2
Common routes to undefined behavior and an important limit:
- A data race occurs when accesses to one memory location in separate threads lack enforced ordering, at least one access is a write, and at least one access is non-atomic. section 5.1.2
- Atomic access can avoid undefined behavior for a raced memory location, though it does not specify which atomic operation occurs first. section 5.1.2
- With std::execution::parallel_policy, a call that permits data races is undefined behavior even if the implementation happens to use only one thread. section 10.2.3
- A lock-free stack pop that dereferences a null head also causes undefined behavior. section 7.2.1
A pointer passed to a detached thread
If a thread receives a pointer to a local character buffer and the function returns before the new thread converts it to std::string, the pointer may outlive the buffer. Constructing the string before passing the argument avoids this timing problem. section 2.2
std::for_each(std::execution::par,v.begin(),v.end(),
[&](int& x){ x=++count; });
!@%STYLE%@!
{"css":"{\"css\": \"font-weight: bold;\"}","target":"[[{\"line\":0,\"ch\":14},{\"line\":0,\"ch\":33}]]"}
!@%STYLE%@!
Each parallel invocation increments shared count without synchronization. Making count atomic or protecting it with a mutex can define access, though synchronization may serialize the calls. section 10.2.3






