简体   繁体   中英

Is there a function to load a non-atomic value atomically?

In C++20 we can write:

double x;

double x_value = std::atomic_ref(x).load();

Is there a function with the same effect?

I have tried std::atomic_load but there seem to be no overloads for non-atomic objects.

Non-portably of course, there is GNU C __atomic_load_n(&x, __ATOMIC_SEQ_CST) __atomic builtin .

I'm pretty sure you don't find a function in ISO C++ that takes a double * or double & .

Possibly one that takes a std::atomic_ref<double> * or reference, I didn't check, but I think the intent of atomic_ref is to be constructed on the fly for free inside a function that needs it.

If you want such a function, write you own that constructs + uses an atomic_ref . It will all inline down to an __atomic_load_n on compilers where atomic uses that under the hood anyway.


But do make sure to declare your global like this, to make sure it's safe + efficient to use with atomic_ref . It's UB (I think) to take an atomic_ref to an object that's not sufficiently aligned, so the atomic_ref constructor can simply assume that the object you use is aligned the same as atomic<T> needs to be.

alignas (std::atomic_ref<double>::required_alignment)  double x;

In practice that's only going to be a problem for 8-byte primitive types like double inside structs on 32-bit targets, but something like struct { char c[8]; } struct { char c[8]; } could in practice be not naturally aligned if you don't ask for alignment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM