3

I want to add two values:

auto size = new std::atomic<double>(0);
double packet_size = 64e3;
*size += packet_size;

But I got an error.

no match for ‘operator+=’ (operand types are ‘std::atomic<double>’ and ‘double’)

How should I correctly add these two numbers?

Kenenbek Arzymatov
  • 8,439
  • 19
  • 58
  • 109

1 Answers1

2

Even tough you can create atomic<float> and atomic<double>, atomic operators are not defined for floating point atomics. This is because there is no x86 (nor ARM) assembly instruction for atomically add floating point values.

A workaround is to use the compare_exchange operations to increment/change your atomic variable.

#include <atomic>

int main()
{
    std::atomic<int> i{};
    i += 3;

    //  Peter Cordes pointed out in a comment below that using 
    //  compare_exchange_weak() may be better suited for most 
    //  uses.
    //  Then again, the needed strength of the exchange depends 
    //  on your application, and the hardware it's intended to run on.  

    std::atomic<double> f{};
    for (double g = f; !f.compare_exchange_strong(g, g + 1.0);)
      ;
    return 0;
}
Michaël Roy
  • 6,338
  • 1
  • 15
  • 19
  • 2
    If you're using a loop already, use `compare_exchange_weak` so it compiles more nicely on LL/SC ISAs like ARM. Otherwise this compiles to a nested loop on ARM. Like most RISC, ARM doesn't have instructions to do any atomic RMW except a paired load/store-conditional, with the ALU operation implemented however you want. – Peter Cordes Nov 19 '19 at 21:42