A thread that is explicitly set to the detached state cannot be joined upon; so, what happens when it dies? Its resources are disposed of by the library.
A thread that is explicitly set to the joinable state (or if joinable is the default state) must be joined upon; failure to do so results in a kind of resource leakage. So, be careful: if you have created threads to be joinable, then you must ensure that the join is performed.
Performing a join on other app threads by the main thread is usually considered a best practice, since it prevents the zombie thread behavior we saw earlier. Also, it's usually important for the creator thread to come to know whether its workers successfully performed their job or not, and if not, why ...