Есть два эквивалентных примера:
#include <stdatomic.h>
int main() {
int v[2], * p0 = v, * _Atomic p1 = v;
if (p0 != p1) return 1;
if (++p0 != ++p1) return 2;
if (++p0 != (atomic_fetch_add_explicit(&p1, 1, memory_order_relaxed), p1)) return 3;
}
#include <atomic>
using namespace std;
int main() {
int v[2], * p0 = v; atomic<int*> p1 = v;
if (p0 != p1) return 1;
if (++p0 != ++p1) return 2;
if (++p0 != (p1.fetch_add(1, memory_order_relaxed), p1)) return 3;
}
C-версия делает return 3. Из-за того, что atomic_fetch_add_explicit(&p1, 1, memory_order_relaxed)
компилируется в lock addq $0x1,-0x10(%rsp)
. В C++ lock addq $0x4,-0x10(%rsp)
- как и должно быть, учитывает тип. Это баг какой-то или так специально сделано? Зачем?