Xiaoying Sun
Xiaoying Sun

Reputation: 29

Segmentation fault error occurs when gcc, but there is no problem with clang

#include <iostream>
#include <thread>
#include <chrono>
#include <functional>

template <typename F, typename... Ts>
inline void FuncDetach(F &&f, Ts &&...args)
{
    std::thread th{[&f, &args...]() {
        do
        {
            auto func = std::bind(std::forward<F>(f), std::forward<Ts>(args)...);
            func(args...);
        } while (true);
    }};
    th.detach();
}

auto func()
{
    std::cout << "normal func" << std::endl;
}

class CL
{
public:
    auto func() {std::cout << "member func" << std::endl;}
};

int main()
{
    FuncDetach(func); // gcc and clang no problem

    CL c;
    FuncDetach(&CL::func, &c); // segmentation fault in gcc, but not in clang
    std::this_thread::sleep_for(std::chrono::minutes(2));
    return 0;
}

There is only "normal func" output in gcc, and then "Segmentation fault" appears. "normal func" and "member func" in clang will always output.

I don't think this has anything to do with the life cycle of c, because it is obvious that c has not been destroyed. At the same time, I also noticed that -lpthread is not required for compiling with clang. So, can someone tell me what the problem is? Thank you very much!

Upvotes: 2

Views: 1436

Answers (1)

Davis Herring
Davis Herring

Reputation: 39953

While c is "never destroyed", the parameters to FuncDetach are references to the temporaries materialized for the prvalue arguments (the pointer-to-member and pointer, respectively), and their by-reference captures become invalid when the call returns (they might live until the end of the full-expression, but that's the same point here). Undefined behavior is undefined.

Upvotes: 1

Related Questions