> On Jun 3, 2019, at 4:32 AM, Andrew Haley <a...@redhat.com> wrote: > > On 6/3/19 7:58 AM, Nick Gasson wrote: >> >>> If I'm reading the gcc documentation for __sync_add_and_fetch >>> correctly, I think the following (completely untested) should work, >>> and won't cause Andrew to (I think rightly) complain about >>> type-punning reinterpret_casts. >>> >>> Though I wonder if this is a clang bug. (See below.) > > It's arguably a mistake in the GCC documentation, but adding two > pointers is not well defined whereas adding a pointer and an integer > is.
Yes, the gcc documentation seems to be a bit botched here. But there is also the semantic description, e.g. for __sync_OP_and_fetch: { *ptr OP= value; return *ptr; } >> Another way round this is to use __atomic_add_fetch instead which both >> Clang and GCC accept: >> >> template<typename I, typename D> >> D add_and_fetch(I add_value, D volatile* dest, atomic_memory_order order) >> const { >> D res = __atomic_add_fetch(dest, add_value, __ATOMIC_RELEASE); >> FULL_MEM_BARRIER; >> return res; >> } > > I could live with that. The __atomic_xxx operations seem to have the same documentation issues. It's strange that clang would get one set right and the other wrong. But okay, using them seems like a good workaround. And maybe someday the order argument will be used to select the barriers to use.