Search code examples
c++atomicstdatomic

C++ std::atomic union


How do I set a union to be atomic using std::atomic? Or do I have to declare the members of the union to be atomic instead?

typedef union {
    int integer;
    float flt;
    double dbl;
    int *intArray;
    float *floatArray;
    unsigned char *byteArray;
} ValueUnion;

class FooClass {
public:
    std::atomic<ValueUnion> value;

}; 

Access to the union gives an error:

foo->value.floatArray = NULL;

error: no member named 'floatArray' in 'std::__1::atomic<ValueUnion>'
                    foo->value.floatArray = NULL;

Do I need to do something like:

typedef union {
    std::atomic<int> integer;
    std::atomic<float> flt;
    std::atomic<double> dbl;
    std::atomic<int*> *intArray;
    std::atomic<float*> *floatArray;
    std::atomic<unsigned char*> *byteArray;
} ValueUnion;

and declare the member variable value to be as below?

class FooClass {
public:
    ValueUnion value;

}; 

Solution

  • It depends what you want to do with it. For example, to store a value into an atomic union:

    foo->value = []{ ValueUnion u; u.floatArray = NULL; return u; }();
    

    or

    foo->value.store([]{ ValueUnion u; u.floatArray = NULL; return u; }());
    

    If you want to be able to perform lock-free atomic arithmetic (e.g. atomic increment) on the contained values then you will need to go for your second design (a union of atomics).