Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Attempting to reference a deleted function (copy c'tor)

I got this example of spinlock from Anthony Williams, and its something wrong with it (or I had a long day).

#include <atomic>
class spinlock 
{
    std::atomic_flag flag;
public:
    spinlock() : flag(ATOMIC_FLAG_INIT) {}
    void lock() {
        while (flag.test_and_set(std::memory_order_acquire));
    }
    void unlock(){
        flag.clear(std::memory_order_release);
    }
};

spinlock sl;
void f() 
{
    std::lock_guard lc(sl);
}

int main()
{
    f();
}

So this is enough for std::lock_guard to acquire it, but I have a compilation error.

error C2280: ‘std::atomic_flag::atomic_flag(const std::atomic_flag &)’: attempting to reference a deleted function

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

To be honest I dont see how spinlock() : flag(ATOMIC_FLAG_INIT) {} is calling a copy constructor.
I use VS2022 with C++20 standard and ATOMIC_FLAG_INIT is defined as following:

#define ATOMIC_FLAG_INIT \
    {}

Is this book example broken, or am I donning something wrong?

>Solution :

ATOMIC_FLAG_INIT can only be used as follows:

std::atomic_flag v = ATOMIC_FLAG_INIT;

It is unspecified if

flag(ATOMIC_FLAG_INIT)

will work. If visual studio defines ATOMIC_FLAG_INIT as {} then your code is presumably ending up creating an std::atomic_flag with {} then calling the deleted copy constructor of flag.

If you’re using c++20 you can simply remove the flag initialiser as std::atomic_flag‘s default constructor now initialises to false.

Without c++20 I think the only way to do this according to the standard is to use an inline initialiser:

class spinlock 
{
    std::atomic_flag flag = ATOMIC_FLAG_INIT;
public:
    void lock() {
        while (flag.test_and_set(std::memory_order_acquire));
    }
    void unlock(){
        flag.clear(std::memory_order_release);
    }
};
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading