2

I am trying to write a class which has a method that can only be called once per object (well, it can be called multiple times, but it will only do something the first time).

My example code is

#include <iostream>
#include <functional>
#include <mutex>
class OneCallClass
{
    private:
    std::once_flag f_once{};

    public:
    void f() 
    {
        std::call_once(f_once, 
            []() { std::cout << "First call\n"; }
        );
     }
};

int main()
{
    OneCallClass o;
    o.f();
    // o.f();
    // o.f();
}

and it fails on Godbolt with the error message

terminate called after throwing an instance of 'std::system_error'
  what():  Unknown error -1
Program terminated with signal: SIGSEGV

The code looks straight forward to me. I looked up cppreference for std::call_once() and I don't see how I'm doing it wrong.

Well, the documentation says

std::system_error if any condition prevents calls to std::call_once from executing as specified

but which condition should that be?

I am creating an instance of the class on the stack. f_once() should be initialized due to {} and therefore I can use the rule of zero, no constructors, destuctors etc.

Where's the bug and how to fix it?

Thomas Weller
  • 55,411
  • 20
  • 125
  • 222

1 Answers1

1

You need -lpthread when using facilities from the thread support library.

Demo

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • 1
    I believe `-pthread` should generally be used instead of `-lpthread`. See the following question for further information: [Difference between -pthread and -lpthread while compiling](https://stackoverflow.com/q/23250863/12149471) – Andreas Wenzel Jul 04 '23 at 13:31
  • @AndreasWenzel I admit its the first time I hear about this difference. I actually believe here `lphtread` is sufficient, because there is only a single thread in OPs code. I'll have to do more reading before I can fix the answer – 463035818_is_not_an_ai Jul 04 '23 at 13:34