# RFC: \_\_atomic\_\* support for gcc 4.7 compatibility

**URL:** <https://discourse.llvm.org/t/rfc-atomic-support-for-gcc-4-7-compatibility/22733>\
**Category:** Clang Frontend\
**Created:** [April 10, 2012, 7:22pm UTC](https://discourse.llvm.org/t/rfc-atomic-support-for-gcc-4-7-compatibility/22733 "2012-04-10T19:22:57Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![zygoloid](https://sea1.discourse-cdn.com/flex021/user_avatar/discourse.llvm.org/zygoloid/32/14068_2.png) [@zygoloid](https://discourse.llvm.org/u/zygoloid)\
**Post date:** [April 10, 2012, 7:22pm UTC](https://discourse.llvm.org/t/rfc-atomic-support-for-gcc-4-7-compatibility/22733/1 "2012-04-10T19:22:57Z")

</div>

Hi,

I’m looking into adding support for gcc 4.7’s \__atomic_\* builtins for the clang 3.1 release (these are necessary to support various parts of libstdc++4.7). Our current set of \__atomic_\* builtins is incompatible with gcc 4.7’s builtins in a few ways:

1. In clang, the builtins produce results by value, whereas in gcc, a pointer is passed indicating where the result should be written.
2. In clang, the argument type must be an \_Atomic. gcc does not have this restriction (but also fails to require that the type is trivially copyable, which is probably a bug).
3. Clang is missing the \__atomic_\*\_n, \_\_atomic\_always\_lock\_free and \_\_atomic\_fetch\_nand builtins.
4. Clang is missing the \_\_atomic\_compare\_exchange builtin, and instead provides \_\_atomic\_compare\_exchange\_strong and \_\_atomic\_compare\_exchange\_weak.
5. Clang provides an \_\_atomic\_init builtin, which gcc does not provide, and which crashes during CodeGen.

My current plan is:

For (1), add support for the gcc-style arguments, then port libc++ over to them, then remove support for the current arguments.  
For (2), relax the requirement to the type being either \_Atomic or trivially copyable.  
For (3) and (4), add the missing builtins. I don’t intend to remove the \_\_atomic\_compare\_exchange\_strong/\_\_atomic\_compare\_exchange\_weak builtins, but will do so if anyone particularly wants to see them gone.  
For (5), remove this builtin.

Please shout now if any part of this displeases you! In particular, if you have code depending on clang’s current pass-by-value atomics and you’d like to see them left in until after the clang 3.1 release to give you more time to move to the portable forms (or indeed you believe they should be left in-place forever), please say so.

Thanks!  
Richard

---

<div class="post-metadata">

**Author:** ![zygoloid](https://sea1.discourse-cdn.com/flex021/user_avatar/discourse.llvm.org/zygoloid/32/14068_2.png) [@zygoloid](https://discourse.llvm.org/u/zygoloid)\
**Post date:** [April 10, 2012, 7:29pm UTC](https://discourse.llvm.org/t/rfc-atomic-support-for-gcc-4-7-compatibility/22733/2 "2012-04-10T19:29:28Z")

</div>

I should clarify: this builtin works fine on scalar types, but crashes in cases like this:

struct T { char v[4]; };  
\_Atomic(T) a;  
void f() { \_\_atomic\_init(&a, T()); }

If this builtin is useful (in particular for C11, since neither libstdc++ nor libc++ need it), I’ll take a look at fixing it instead of removing it.

---

<div class="post-metadata">

**Author:** ![David\_Chisnall4](https://avatars.discourse-cdn.com/v4/letter/d/c67d28/32.png) [@David\_Chisnall4](https://discourse.llvm.org/u/David_Chisnall4)\
**Post date:** [April 10, 2012, 7:58pm UTC](https://discourse.llvm.org/t/rfc-atomic-support-for-gcc-4-7-compatibility/22733/3 "2012-04-10T19:58:50Z")

</div>

> Hi,
> 
> I'm looking into adding support for gcc 4.7's \_\_atomic\_\* builtins for the clang 3.1 release (these are necessary to support various parts of libstdc++4.7). Our current set of \_\_atomic\_\* builtins is incompatible with gcc 4.7's builtins in a few ways:

While it would be nice to build libstdc++, it should be noted that the gcc builtins are poorly designed in a number of ways and I don't think we should be encouraging their use by supporting them in anything other than the specific case of supporting libstdc++. The clang ones are a closer match for the C11 spec (and we should really be encouraging people to use stdatomic.h, rather than using the intrinsics directly anyway).

> 1) In clang, the builtins produce results by value, whereas in gcc, a pointer is passed indicating where the result should be written.

This means that the things required by C11's stdatomic.h can be trivially implemented as macros (just dropping the \_\_ prefix) with the clang builtins. They can not with the GCC ones in their standard form, although the \_n versions can be used this way. I am not sure what the perceived advantage of the GCC non-\_n ones is.

> 2) In clang, the argument type must be an \_Atomic. gcc does not have this restriction (but also fails to require that the type is trivially copyable, which is probably a bug).

This is a horrible bug in GCC, because it means that you can have atomic and non-atomic accesses to the same memory address (something explicitly not allowed by C11). This is part of the reason for the \_Atomic() qualifier. It also changes the alignment requirements of certain types, in both gcc and clang, which can lead to really hard-to-track-down bugs as a result of sloppy casting.

I would strongly oppose supporting using the builtins with types that are not \_Atomic-qualified, because doing so makes it trivial to introduce a large number of very subtle bugs.

> 3) Clang is missing the \_\_atomic\_\*\_n, \_\_atomic\_always\_lock\_free and \_\_atomic\_fetch\_nand builtins.

The \_n builtins actually do what the current clang ones do. \_\_atomic\_always\_lock\_free is probably useful. \_\_atomic\_fetch\_nand might be as well, although it isn't needed by C++11 or C11.

> 4) Clang is missing the \_\_atomic\_compare\_exchange builtin, and instead provides \_\_atomic\_compare\_exchange\_strong and \_\_atomic\_compare\_exchange\_weak.

I'm not sure what the point of the GCC version is. The strong / weak option affects code generation, it's not something that can be selected at run time, so having a bool parameter just makes code less readable.

> 5) Clang provides an \_\_atomic\_init builtin, which gcc does not provide, and which crashes during CodeGen.

This is required for C11. I'll take a look at the crash. It's also used by libc++. \_\_atomic\_init() initialises an \_Atomic type without performing an atomic operation (as per both C++11 and C11). Or, at least, it should...

I believe that libstdc++ gets around this by not \_Atomic-qualifying the types and then using normal initialisation. This is... problematic, to say the least, as an approach.

> My current plan is:
> 
> For (1), add support for the gcc-style arguments, then port libc++ over to them, then remove support for the current arguments.

Please don't.

> For (2), relax the requirement to the type being either \_Atomic or trivially copyable.

I think this would be a serious mistake. Allowing atomic operations on non-\_Atomic types in the intrinsics makes it insanely hard to correctly implement C11 stdatomic.h and will cause all sorts of problems for users of these builtins later.

> For (3) and (4), add the missing builtins. I don't intend to remove the \_\_atomic\_compare\_exchange\_strong/\_\_atomic\_compare\_exchange\_weak builtins, but will do so if anyone particularly wants to see them gone.

As with the other clang builtins, they make stdatomic.h much easier to implement. From FreeBSD's stdatomic.h:

#if defined(\_\_CLANG\_ATOMICS)  
#define atomic\_compare\_exchange\_strong\_explicit(object, expected, \  
&nbsp;&nbsp;&nbsp;&nbsp;desired, success, failure) \  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\_\_atomic\_compare\_exchange\_strong(object, expected, desired, \  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;success, failure)  
#define atomic\_compare\_exchange\_weak\_explicit(object, expected, \  
&nbsp;&nbsp;&nbsp;&nbsp;desired, success, failure) \  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\_\_atomic\_compare\_exchange\_weak(object, expected, desired, \  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;success, failure)

Replacing these with a bool parameter would probably be okay, but it makes the code less readable. Which of these do you find easier to understand?

\_\_atomic\_compare\_exchange\_strong(&a, &new, 12, \_\_ATOMIC\_SEQ\_CST, \_\_ATOMIC\_RELAXED);

Or:

\_\_atomic\_compare\_exchange\_strong(&a, &new, 12, true, \_\_ATOMIC\_SEQ\_CST, \_\_ATOMIC\_RELAXED);

What is that true for? What happens if it's a variable? I honestly have no idea - switching between strong and weak implementations at run time is more or less impossible.

> For (5), remove this builtin.

Again, please don't, it is required for C11 and makes achieving the correct semantics for C++11 much easier.

> Please shout now if any part of this displeases you! In particular, if you have code depending on clang's current pass-by-value atomics and you'd like to see them left in until after the clang 3.1 release to give you more time to move to the portable forms (or indeed you believe they should be left in-place forever), please say so.

See above.

David

-- Sent from my Cray X1

---

<div class="post-metadata">

**Author:** ![zygoloid](https://sea1.discourse-cdn.com/flex021/user_avatar/discourse.llvm.org/zygoloid/32/14068_2.png) [@zygoloid](https://discourse.llvm.org/u/zygoloid)\
**Post date:** [April 10, 2012, 9:11pm UTC](https://discourse.llvm.org/t/rfc-atomic-support-for-gcc-4-7-compatibility/22733/4 "2012-04-10T21:11:20Z")

</div>

> > Hi,
> > 
> > I’m looking into adding support for gcc 4.7’s \__atomic_\* builtins for the clang 3.1 release (these are necessary to support various parts of libstdc++4.7). Our current set of \__atomic_\* builtins is incompatible with gcc 4.7’s builtins in a few ways:
> 
> While it would be nice to build libstdc++, it should be noted that the gcc builtins are poorly designed in a number of ways and I don’t think we should be encouraging their use by supporting them in anything other than the specific case of supporting libstdc++.

I agree, but I think this is a problem of documentation. On that subject, do we have documentation for our current \__atomic_ builtins somewhere?

> > 1. In clang, the builtins produce results by value, whereas in gcc, a pointer is passed indicating where the result should be written.
> 
> This means that the things required by C11’s stdatomic.h can be trivially implemented as macros (just dropping the \_\_ prefix) with the clang builtins. They can not with the GCC ones in their standard form, although the \_n versions can be used this way. I am not sure what the perceived advantage of the GCC non-\_n ones is.
> 
> > 1. In clang, the argument type must be an \_Atomic. gcc does not have this restriction (but also fails to require that the type is trivially copyable, which is probably a bug).
> 
> This is a horrible bug in GCC, because it means that you can have atomic and non-atomic accesses to the same memory address (something explicitly not allowed by C11). This is part of the reason for the \_Atomic() qualifier. It also changes the alignment requirements of certain types, in both gcc and clang, which can lead to really hard-to-track-down bugs as a result of sloppy casting.

I don’t see that this is obviously a bug in gcc – it does not support \_Atomic, and (as you suggested above) presumably expects its builtins to be used only to implement \<stdatomic.h\> and (or by people who know what they’re doing and want to circumvent the normal protections).

> I would strongly oppose supporting using the builtins with types that are not \_Atomic-qualified, because doing so makes it trivial to introduce a large number of very subtle bugs.

Such support is necessary to support libstdc++'s . I think you’ve made a reasonable case that we should have two sets of builtins, a C11-style set (the current builtins) and a GCC-compatible set. To this end, I would strongly prefer for them to have different names, so that the trivial mapping of \<stdatomic.h\> names to builtins never accidentally uses the GCC-compatible builtins. Unfortunately, that seems to require renaming the C11-style builtins (unless someone has a better suggestion).

> > 1. Clang is missing the \__atomic_\*\_n, \_\_atomic\_always\_lock\_free and \_\_atomic\_fetch\_nand builtins.
> 
> The \_n builtins actually do what the current clang ones do.

Functionally, yes, but the \_Atomic check makes clang’s implementations unusable for libstdc++, and the \_n variants are required to check that the argument type is a 1, 2, 4, 8 or 16-byte integer or pointer type.

> \_\_atomic\_always\_lock\_free is probably useful. \_\_atomic\_fetch\_nand might be as well, although it isn’t needed by C++11 or C11.

Right. I consider \_\_atomic\_fetch\_nand and \_\_atomic\_always\_lock\_free to be a low priority (not necessary for 3.1) since libstdc++4.7 does not use them.

> > 1. Clang is missing the \_\_atomic\_compare\_exchange builtin, and instead provides \_\_atomic\_compare\_exchange\_strong and \_\_atomic\_compare\_exchange\_weak.
> 
> I’m not sure what the point of the GCC version is. The strong / weak option affects code generation, it’s not something that can be selected at run time, so having a bool parameter just makes code less readable.

GCC’s (documented) approach is to use the strong version if it cannot prove the ‘weak’ bool is true. I agree that this seems like a strange choice (and indeed in libstdc++ the ‘weak’ flag is always one of 0, 1, false, or true), but it’s necessary for libstdc++ compatibility, so if we want such compatibility, our aesthetic preferences are somewhat irrelevant.

The same objection also applies to the memory order parameter (where GCC always uses seq\_cst if it can’t determine the argument at build-time, and clang generates a branch).

> > 1. Clang provides an \_\_atomic\_init builtin, which gcc does not provide, and which crashes during CodeGen.
> 
> This is required for C11. I’ll take a look at the crash. It’s also used by libc++. \_\_atomic\_init() initialises an \_Atomic type without performing an atomic operation (as per both C++11 and C11). Or, at least, it should…
> 
> I believe that libstdc++ gets around this by not \_Atomic-qualifying the types and then using normal initialisation. This is… problematic, to say the least, as an approach.

libc++ does not currently use \_\_atomic\_init; it uses a sequentially-consistent \_\_atomic\_store instead. I agree that that seems highly suboptimal, and that we should keep this builtin.

> > My current plan is:
> > 
> > For (1), add support for the gcc-style arguments, then port libc++ over to them, then remove support for the current arguments.
> 
> Please don’t.

Your objections thus far have not been strong enough, in my opinion, to justify abandoning libstdc++4.7 support for clang, nor to justify abandoning g++ support for libc++ (although naturally that will be Howard’s choice). I’m not opposed to keeping the existing builtins too, as distasteful as it is to have two competing, and very similar, sets.

> > For (2), relax the requirement to the type being either \_Atomic or trivially copyable.
> 
> I think this would be a serious mistake. Allowing atomic operations on non-\_Atomic types in the intrinsics makes it insanely hard to correctly implement C11 stdatomic.h and will cause all sorts of problems for users of these builtins later.

Given the above approach to (1), I think the best plan here would be to leave the C11 intrinsics alone and require the argument for the GNU intrinsics to be trivially-copyable. Thus the GNU intrinsics would not work with \_Atomic types, and the \_Atomic intrinsics would not work with non-\_Atomic types.

> > For (3) and (4), add the missing builtins. I don’t intend to remove the \_\_atomic\_compare\_exchange\_strong/\_\_atomic\_compare\_exchange\_weak builtins, but will do so if anyone particularly wants to see them gone.
> 
> As with the other clang builtins, they make stdatomic.h much easier to implement.

[…]

As I said, I don’t intend to remove the strong/weak variants.

> > For (5), remove this builtin.
> 
> Again, please don’t, it is required for C11 and makes achieving the correct semantics for C++11 much easier.

Agreed.

Many thanks for your feedback!  
Richard

---

<div class="post-metadata">

**Author:** ![David\_Chisnall](https://avatars.discourse-cdn.com/v4/letter/d/5fc32e/32.png) [@David\_Chisnall](https://discourse.llvm.org/u/David_Chisnall)\
**Post date:** [April 10, 2012, 9:25pm UTC](https://discourse.llvm.org/t/rfc-atomic-support-for-gcc-4-7-compatibility/22733/5 "2012-04-10T21:25:21Z")

</div>

> \> Hi,  
> \>  
> \> I'm looking into adding support for gcc 4.7's \_\_atomic\_\* builtins for the clang 3.1 release (these are necessary to support various parts of libstdc++4.7). Our current set of \_\_atomic\_\* builtins is incompatible with gcc 4.7's builtins in a few ways:
> 
> While it would be nice to build libstdc++, it should be noted that the gcc builtins are poorly designed in a number of ways and I don't think we should be encouraging their use by supporting them in anything other than the specific case of supporting libstdc++.
> 
> I agree, but I think this is a problem of documentation. On that subject, do we have documentation for our current \_\_atomic\_ builtins somewhere?

The documentation is the C11 spec. The builtins have a 1:1 correspondence with the C11 generic functions in stdatomic.h.

> \> 2) In clang, the argument type must be an \_Atomic. gcc does not have this restriction (but also fails to require that the type is trivially copyable, which is probably a bug).
> 
> This is a horrible bug in GCC, because it means that you can have atomic and non-atomic accesses to the same memory address (something explicitly not allowed by C11). This is part of the reason for the \_Atomic() qualifier. It also changes the alignment requirements of certain types, in both gcc and clang, which can lead to really hard-to-track-down bugs as a result of sloppy casting.
> 
> I don't see that this is obviously a bug in gcc -- it does not support \_Atomic, and (as you suggested above)

In that case, it is an additional bug, because its documentation on its atomic implementation indicates that it does.

> presumably expects its builtins to be used only to implement \<stdatomic.h\> and \<atomic\> (or by people who know what they're doing and want to circumvent the normal protections).

As I said, it's very difficult to enforce the requirement that \_Atomic operations only be accessed atomically in C (not so hard in C++, where you have operator overloading). For example, in C11 this:

\_Atomic(int) i;  
...  
i++;

Is an atomic increment. And so is this:

atomic\_fetch\_add\_explicit(&i, 1, memory\_order\_seq\_cst);

But this i++ is not atomic if i is not \_Atomic-qualified, and atomic\_fetch\_add\_explicit() is undefined in this case.

> I would strongly oppose supporting using the builtins with types that are not \_Atomic-qualified, because doing so makes it trivial to introduce a large number of very subtle bugs.
> 
> Such support is necessary to support libstdc++'s \<atomic\>. I think you've made a reasonable case that we should have two sets of builtins, a C11-style set (the current builtins) and a GCC-compatible set. To this end, I would strongly prefer for them to have different names, so that the trivial mapping of \<stdatomic.h\> names to builtins never accidentally uses the GCC-compatible builtins. Unfortunately, that seems to require renaming the C11-style builtins (unless someone has a better suggestion).

I believe that it's possible to implement the GCC ones in a terms of the clang ones in a header, if they're required for libstdc++. If libstdc++ is the only consumer of them, then an \<atomic\> that did this and then #include\_next'd the libstdc++ one might be a better solution.

> \> 3) Clang is missing the \_\_atomic\_\*\_n, \_\_atomic\_always\_lock\_free and \_\_atomic\_fetch\_nand builtins.
> 
> The \_n builtins actually do what the current clang ones do.
> 
> Functionally, yes, but the \_Atomic check makes clang's implementations unusable for libstdc++, and the \_n variants are  
> required to check that the argument type is a 1, 2, 4, 8 or 16-byte integer or pointer type.

The latter requirement is not required by either C++11 or C11.

> \_\_atomic\_always\_lock\_free is probably useful. \_\_atomic\_fetch\_nand might be as well, although it isn't needed by C++11 or C11.
> 
> Right. I consider \_\_atomic\_fetch\_nand and \_\_atomic\_always\_lock\_free to be a low priority (not necessary for 3.1) since libstdc++4.7 does not use them.
> 
> \> 4) Clang is missing the \_\_atomic\_compare\_exchange builtin, and instead provides \_\_atomic\_compare\_exchange\_strong and \_\_atomic\_compare\_exchange\_weak.
> 
> I'm not sure what the point of the GCC version is. The strong / weak option affects code generation, it's not something that can be selected at run time, so having a bool parameter just makes code less readable.
> 
> GCC's (documented) approach is to use the strong version if it cannot prove the 'weak' bool is true. I agree that this seems like a strange choice (and indeed in libstdc++ the 'weak' flag is always one of 0, 1, false, or true), but it's necessary for libstdc++ compatibility, so if we want such compatibility, our aesthetic preferences are somewhat irrelevant.

#define \_\_atomic\_compare\_exchage(a,b,c,d,e) \_\_atomic\_compare\_exchange\_strong(a,b,d,e)

> The same objection also applies to the memory order parameter (where GCC always uses seq\_cst if it can't determine the argument at build-time, and clang generates a branch).

The difference being that the C11 and C++11 specs make the memory order parameters explicit, but they make the strong / weak version part of the operation name.

> \> 5) Clang provides an \_\_atomic\_init builtin, which gcc does not provide, and which crashes during CodeGen.
> 
> This is required for C11. I'll take a look at the crash. It's also used by libc++. \_\_atomic\_init() initialises an \_Atomic type without performing an atomic operation (as per both C++11 and C11). Or, at least, it should...
> 
> I believe that libstdc++ gets around this by not \_Atomic-qualifying the types and then using normal initialisation. This is... problematic, to say the least, as an approach.
> 
> libc++ does not currently use \_\_atomic\_init; it uses a sequentially-consistent \_\_atomic\_store instead.

That's a bug then. The C++11 spec explicitly states that initialisation is NOT atomic (as Howard pointed out to me when I tried to introduce this bug in libc++).

> I agree that that seems highly suboptimal, and that we should keep this builtin.  
> \> My current plan is:  
> \>  
> \> For (1), add support for the gcc-style arguments, then port libc++ over to them, then remove support for the current arguments.
> 
> Please don't.
> 
> Your objections thus far have not been strong enough, in my opinion, to justify abandoning libstdc++4.7 support for clang, nor to justify abandoning g++ support for libc++ (although naturally that will be Howard's choice). I'm not opposed to keeping the existing builtins too, as distasteful as it is to have two competing, and very similar, sets.

I'm not opposing supporting libstdc++, but I am not convinced that introducing a set of poorly designed intrinsics is the correct way of doing it, especially since we would be forced to support them long-term.

-- Sent from my Cray X1

---

<div class="post-metadata">

**Author:** ![Howard\_Hinnant](https://avatars.discourse-cdn.com/v4/letter/h/ba8739/32.png) [@Howard\_Hinnant](https://discourse.llvm.org/u/Howard_Hinnant)\
**Post date:** [April 10, 2012, 9:57pm UTC](https://discourse.llvm.org/t/rfc-atomic-support-for-gcc-4-7-compatibility/22733/6 "2012-04-10T21:57:01Z")

</div>

It looks like we have a couple of questions:

1. Does clang support libstdc++ \<atomic\>?

2. Does libc++ \<atomic\> support gcc?

I have no opinion on 1. I will leave that to the clang developers.

On 2, I have no motivation to support gcc. gcc has its own std::lib solution and the GPL is not compatible with libc++ licensing. However if there are members of this community that wish to support gcc (and wish to do the work to make it so), and if there is zero run time and code size overhead, and if the compile time overhead is negligible, I have no objection. I will cringe at the ugliness it will introduce to the source, but I can live with that.

Since I do not care about gcc compatibility, I prefer whatever intrinsics have the most seamless matching to C11/C++11. I'm under the impression that this is the current clang design, but I am not expert in this area.

I do not understand the need for \_\_atomic\_init. The atomic constructors that currently look like:

&nbsp;&nbsp;&nbsp;&nbsp;/\*constexpr\*/ \_\_atomic\_base(\_Tp \_\_d) { \_\_atomic\_store(&\_\_a\_, \_\_d, memory\_order\_seq\_cst); }

used to look like:

&nbsp;&nbsp;&nbsp;/\*constexpr\*/ \_\_atomic\_base(\_Tp \_\_d) : \_\_a\_(\_\_d) {}

and it is my understanding that the latter is correct.

If the latter has the correct semantics, I prefer it to:

&nbsp;&nbsp;&nbsp;/\*constexpr\*/ \_\_atomic\_base(\_Tp \_\_d) {\_\_atomic\_init(&\_\_a\_, \_\_d);}

An intrinsic that does nothing but initialize the same way a C/C++ statement would do, adds no value, but does add confusion over what it is doing. If \_\_atomic\_init does add needed functionality, then of course I would agree that we need it.

David, could you revert the initialization statements to use either plain C++, or the \_\_atomic\_init intrinsic?

\<atomic\> also needs to be treated with constexpr and noexcept, although there is no rush to do that prior to having the intrinsics fully operational (or are they already?).

Thanks,  
Howard

---

<div class="post-metadata">

**Author:** ![David\_Chisnall](https://avatars.discourse-cdn.com/v4/letter/d/5fc32e/32.png) [@David\_Chisnall](https://discourse.llvm.org/u/David_Chisnall)\
**Post date:** [April 10, 2012, 10:11pm UTC](https://discourse.llvm.org/t/rfc-atomic-support-for-gcc-4-7-compatibility/22733/7 "2012-04-10T22:11:11Z")

</div>

Sorry, I thought I'd done that already when I fixed initialisation of \_Atomic types in clang. I'm just about to fall asleep, but I'll do it in the morning.

\_\_atomic\_init() is still required for atomic\_init() (in both C11 and C++11) - these are currently using \_\_atomic\_store, in libc++, so I'll fix them at the same time.

David

---

<div class="post-metadata">

**Author:** ![Howard\_Hinnant](https://avatars.discourse-cdn.com/v4/letter/h/ba8739/32.png) [@Howard\_Hinnant](https://discourse.llvm.org/u/Howard_Hinnant)\
**Post date:** [April 10, 2012, 10:20pm UTC](https://discourse.llvm.org/t/rfc-atomic-support-for-gcc-4-7-compatibility/22733/8 "2012-04-10T22:20:20Z")

</div>

> > David, could you revert the initialization statements to use either plain C++, or the \_\_atomic\_init intrinsic?
> 
> Sorry, I thought I'd done that already when I fixed initialisation of \_Atomic types in clang. I'm just about to fall asleep, but I'll do it in the morning.

Of course. I'd much rather you be awake when you do this. 🙂

> \_\_atomic\_init() is still required for atomic\_init() (in both C11 and C++11) - these are currently using \_\_atomic\_store, in libc++, so I'll fix them at the same time.

template \<class \_Tp\>  
inline \_LIBCPP\_INLINE\_VISIBILITY  
void  
atomic\_init(atomic\<\_Tp\>\* \_\_o, \_Tp \_\_d)  
{  
&nbsp;&nbsp;&nbsp;&nbsp;\_\_o-\>\_\_a\_ = \_\_d;  
}

Not right?

Howard

---

<div class="post-metadata">

**Author:** ![zygoloid](https://sea1.discourse-cdn.com/flex021/user_avatar/discourse.llvm.org/zygoloid/32/14068_2.png) [@zygoloid](https://discourse.llvm.org/u/zygoloid)\
**Post date:** [April 10, 2012, 10:25pm UTC](https://discourse.llvm.org/t/rfc-atomic-support-for-gcc-4-7-compatibility/22733/9 "2012-04-10T22:25:47Z")

</div>

> > > Hi,
> > > 
> > > I’m looking into adding support for gcc 4.7’s \__atomic_\* builtins for the clang 3.1 release (these are necessary to support various parts of libstdc++4.7). Our current set of \__atomic_\* builtins is incompatible with gcc 4.7’s builtins in a few ways:
> > 
> > While it would be nice to build libstdc++, it should be noted that the gcc builtins are poorly designed in a number of ways and I don’t think we should be encouraging their use by supporting them in anything other than the specific case of supporting libstdc++.
> > 
> > I agree, but I think this is a problem of documentation. On that subject, do we have documentation for our current \__atomic_ builtins somewhere?
> 
> The documentation is the C11 spec. The builtins have a 1:1 correspondence with the C11 generic functions in stdatomic.h.

The C11 spec does not talk about \__atomic_\*. A statement in our documentation saying that these builtins implement the \<stdatomic.h\> operations of the same name would be useful (especially since our builtins have the same name as, but different behaviour from, the GCC builtins).

> > I would strongly oppose supporting using the builtins with types that are not \_Atomic-qualified, because doing so makes it trivial to introduce a large number of very subtle bugs.

> > Such support is necessary to support libstdc++'s . I think you’ve made a reasonable case that we should have two sets of builtins, a C11-style set (the current builtins) and a GCC-compatible set. To this end, I would strongly prefer for them to have different names, so that the trivial mapping of \<stdatomic.h\> names to builtins never accidentally uses the GCC-compatible builtins. Unfortunately, that seems to require renaming the C11-style builtins (unless someone has a better suggestion).
> 
> I believe that it’s possible to implement the GCC ones in a terms of the clang ones in a header, if they’re required for libstdc++. If libstdc++ is the only consumer of them, then an that did this and then #include\_next’d the libstdc++ one might be a better solution.

I assume you’re suggesting that we cast the argument from T\* to \_Atomic(T\*) prior to passing it into the builtin? That’s ugly, but seems like it might be workable if \_Atomic(T) always has the same size and alignment as T. I don’t know if those properties hold, but I understand the intent of \_Atomic() was that they need not. (We would also need to ensure TBAA knows that T and \_Atomic(T) can alias.)

This approach, including the need to interpose in front of and \<shared\_ptr\> (and any other user of the atomics builtins in libstdc++) and detect whether we’re about to include a header from libstdc++, seems sufficiently fragile that I’m still in favour of introducing GNU-compatible builtins.

> > > 1. Clang is missing the \__atomic_\*\_n, \_\_atomic\_always\_lock\_free and \_\_atomic\_fetch\_nand builtins.
> > 
> > The \_n builtins actually do what the current clang ones do.
> > 
> > Functionally, yes, but the \_Atomic check makes clang’s implementations unusable for libstdc++, and the \_n variants are  
> > required to check that the argument type is a 1, 2, 4, 8 or 16-byte integer or pointer type.
> 
> The latter requirement is not required by either C++11 or C11.

If we want to fully support the GNU-style atomics, we should implement them correctly. (Naturally, if we’re using your compatibility-shim approach, we needn’t worry about this.)

> > > My current plan is:
> > > 
> > > For (1), add support for the gcc-style arguments, then port libc++ over to them, then remove support for the current arguments.
> > 
> > Please don’t.
> > 
> > Your objections thus far have not been strong enough, in my opinion, to justify abandoning libstdc++4.7 support for clang, nor to justify abandoning g++ support for libc++ (although naturally that will be Howard’s choice). I’m not opposed to keeping the existing builtins too, as distasteful as it is to have two competing, and very similar, sets.
> 
> I’m not opposing supporting libstdc++, but I am not convinced that introducing a set of poorly designed intrinsics is the correct way of doing it, especially since we would be forced to support them long-term.

I share your concern. On the other hand, we have a long history of supporting gcc features, even when we think their design is questionable, for compatibility.

- Richard

---

<div class="post-metadata">

**Author:** ![Chandler\_Carruth](https://avatars.discourse-cdn.com/v4/letter/c/9de053/32.png) [@Chandler\_Carruth](https://discourse.llvm.org/u/Chandler_Carruth)\
**Post date:** [April 10, 2012, 11:14pm UTC](https://discourse.llvm.org/t/rfc-atomic-support-for-gcc-4-7-compatibility/22733/10 "2012-04-10T23:14:09Z")

</div>

To comment first on your high level questions, because I think it’s important to quickly get some consensus here.

> It looks like we have a couple of questions:
> 
> 1. Does clang support libstdc++ ?
> 
> 2. Does libc++ support gcc?
> 
> I have no opinion on 1. I will leave that to the clang developers.

For us, this is a simple necessity. We cannot use Clang without also using libstdc++ at least for the time being. I don’t claim that this is a perfect state of the world, but it is a strongly desirable one.

One perhaps important point – the libstdc++ developers have thus far been perfectly receptive of C++ conformance patches only required for Clang. While it seems hopeless to get them to not support GCC builtins, they are meeting us part of the way there.

Also note that we have a long history in Clang of supporting GCC builtins to ease migration. I see the atomics in a very similar light.

> On 2, I have no motivation to support gcc. gcc has its own std::lib solution and the GPL is not compatible with libc++ licensing. However if there are members of this community that wish to support gcc (and wish to do the work to make it so), and if there is zero run time and code size overhead, and if the compile time overhead is negligible, I have no objection. I will cringe at the ugliness it will introduce to the source, but I can live with that.

I would like to suggest that we aim for this as well. Certainly for us, it helps to have both standard libraries and compilers be cross-tested with each other. This makes evaluating them independently and supporting them in different contexts easier and more predictable.

I generally think that as the less-adopted system, it would benefit libc++ (similarly to the way it benefits Clang) to be as compatible as it is reasonable to be.

That said, I do firmly agree with your restrictions: it should never make using libc++ with Clang _worse_ only to get support for GCC. Users should not pay for what they do not need.

---

<div class="post-metadata">

**Author:** ![Chandler\_Carruth](https://avatars.discourse-cdn.com/v4/letter/c/9de053/32.png) [@Chandler\_Carruth](https://discourse.llvm.org/u/Chandler_Carruth)\
**Post date:** [April 10, 2012, 11:24pm UTC](https://discourse.llvm.org/t/rfc-atomic-support-for-gcc-4-7-compatibility/22733/11 "2012-04-10T23:24:52Z")

</div>

I want to call out this point:

> This approach, including the need to interpose in front of and \<shared\_ptr\> (and any other user of the atomics builtins in libstdc++) and detect whether we’re about to include a header from libstdc++, seems sufficiently fragile that I’m still in favour of introducing GNU-compatible builtins.

I think this is setting ourselves up for an endless game of catchup. What is worse, our users will suffer.

Version skew between libstdc++ and Clang is inevitable. As a consequence, the advantages of being maximally compatible with libstdc++ are only present when we can be largely _forward_ compatible. This seems impossible if we have to intercept ever header to reference a GCC builtin and introduce our wrapper for it.

At a fundamental level, I am not yet comfortable with Clang, after defining **GNUC** and acting as a heavily compatible compiler with GCC, going on to define builtin functions which share the same name but incompatible semantics with GCC builtins. This seems like a recipe for a long string of puzzling compilation failures, user frustration, and impeded adoption of Clang.

I think we should continue with the long standing policy of, when reasonable and tenable, supporting the GCC builtins with their names, and allowing users to not care. Then, under a _different_ naming pattern, and guarded by proper \_\_has\_feature macros etc, we should provide Clang-specific extensions which have the semantics we would rather see.

While a realize this isn’t ideal, and it requires renaming currently supported intrinsics I see few options left to us:

1. We haven’t released with these intrinsics
2. GCC has released with its intrinsics
3. We failed to discuss our intrinsics sufficiently with the GCC folks to get them to implement the same set
4. GCC folks failed to discuss theirs with us sufficiently to get us to implement the same set
5. We need something for Clang v3.1, or it is instantly un-usable with GCC 4.7 and later.

I don’t like any of this, and it isn’t how I would wish for things to proceed if I had it to do again, but this is where we are. We need to realize that, today, I cannot compile any meaningful C++98 code with the default C++ standard library on Linux (after a distro picks up GCC 4.7) and Clang. I do not think that is an acceptable state to release Clang under.

---

<div class="post-metadata">

**Author:** ![Howard\_Hinnant](https://avatars.discourse-cdn.com/v4/letter/h/ba8739/32.png) [@Howard\_Hinnant](https://discourse.llvm.org/u/Howard_Hinnant)\
**Post date:** [April 10, 2012, 11:59pm UTC](https://discourse.llvm.org/t/rfc-atomic-support-for-gcc-4-7-compatibility/22733/12 "2012-04-10T23:59:51Z")

</div>

Perhaps we need to stake out another namespace for clang atomic intrinsics. Our current prefix is:

\_\_atomic\_

Suggestions:

\_\_clang\_atomic\_  
\_\_clng\_atmc\_  
\_ClangAtomic\_  
\_CLNGatomic\_  
\_CLNG\_ATM\_  
\_ClngAtm\_

The final suggestion has the same length as our current prefix.

Howard

---

<div class="post-metadata">

**Author:** ![Howard\_Hinnant](https://avatars.discourse-cdn.com/v4/letter/h/ba8739/32.png) [@Howard\_Hinnant](https://discourse.llvm.org/u/Howard_Hinnant)\
**Post date:** [April 11, 2012, 12:03am UTC](https://discourse.llvm.org/t/rfc-atomic-support-for-gcc-4-7-compatibility/22733/13 "2012-04-11T00:03:03Z")

</div>

Or even shorter: 🙂

\_\_atomx\_

Howard

---

<div class="post-metadata">

**Author:** ![Chandler\_Carruth](https://avatars.discourse-cdn.com/v4/letter/c/9de053/32.png) [@Chandler\_Carruth](https://discourse.llvm.org/u/Chandler_Carruth)\
**Post date:** [April 11, 2012, 12:08am UTC](https://discourse.llvm.org/t/rfc-atomic-support-for-gcc-4-7-compatibility/22733/14 "2012-04-11T00:08:29Z")

</div>

I am quite lazy when it comes to typing, but perhaps here is not the time to save characters. ;] I would vote:

\__clang\_atomic_

or, based on the discussion between David and Richard, perhaps:

\__c11\_atomic_

to call out their close correspondance with the c11 spec.

---

<div class="post-metadata">

**Author:** ![Jean-Daniel\_Dupas1](https://avatars.discourse-cdn.com/v4/letter/j/d9b06d/32.png) [@Jean-Daniel\_Dupas1](https://discourse.llvm.org/u/Jean-Daniel_Dupas1)\
**Post date:** [April 11, 2012, 12:29am UTC](https://discourse.llvm.org/t/rfc-atomic-support-for-gcc-4-7-compatibility/22733/15 "2012-04-11T00:29:25Z")

</div>

> > > > I want to call out this point:
> > > > 
> > > > This approach, including the need to interpose in front of and \<shared\_ptr\> (and any other user of the atomics builtins in libstdc++) and detect whether we’re about to include a header from libstdc++, seems sufficiently fragile that I’m still in favour of introducing GNU-compatible builtins.
> > > > 
> > > > I think this is setting ourselves up for an endless game of catchup. What is worse, our users will suffer.
> > > > 
> > > > Version skew between libstdc++ and Clang is inevitable. As a consequence, the advantages of being maximally compatible with libstdc++ are only present when we can be largely _forward_ compatible. This seems impossible if we have to intercept ever header to reference a GCC builtin and introduce our wrapper for it.
> > > > 
> > > > At a fundamental level, I am not yet comfortable with Clang, after defining **GNUC** and acting as a heavily compatible compiler with GCC, going on to define builtin functions which share the same name but incompatible semantics with GCC builtins. This seems like a recipe for a long string of puzzling compilation failures, user frustration, and impeded adoption of Clang.
> > > > 
> > > > I think we should continue with the long standing policy of, when reasonable and tenable, supporting the GCC builtins with their names, and allowing users to not care. Then, under a _different_ naming pattern, and guarded by proper \_\_has\_feature macros etc, we should provide Clang-specific extensions which have the semantics we would rather see.
> > > > 
> > > > While a realize this isn’t ideal, and it requires renaming currently supported intrinsics I see few options left to us:
> > > > 
> > > > 1. We haven’t released with these intrinsics
> > > > 2. GCC has released with its intrinsics
> > > > 3. We failed to discuss our intrinsics sufficiently with the GCC folks to get them to implement the same set
> > > > 4. GCC folks failed to discuss theirs with us sufficiently to get us to implement the same set
> > > > 5. We need something for Clang v3.1, or it is instantly un-usable with GCC 4.7 and later.
> > > > 
> > > > I don’t like any of this, and it isn’t how I would wish for things to proceed if I had it to do again, but this is where we are. We need to realize that, today, I cannot compile any meaningful C++98 code with the default C++ standard library on Linux (after a distro picks up GCC 4.7) and Clang. I do not think that is an acceptable state to release Clang under.
> > > 
> > > Perhaps we need to stake out another namespace for clang atomic intrinsics. Our current prefix is:
> > > 
> > > \__atomic_
> > > 
> > > Suggestions:
> > > 
> > > \__clang\_atomic_  
> > > \__clng\_atmc_  
> > > _ClangAtomic_  
> > > _CLNGatomic_  
> > > _CLNG\_ATM_  
> > > _ClngAtm_
> > > 
> > > The final suggestion has the same length as our current prefix.
> > 
> > Or even shorter: 🙂
> > 
> > \__atomx_
> 
> I am quite lazy when it comes to typing, but perhaps here is not the time to save characters. ;] I would vote:
> 
> \__clang\_atomic_

The prefix length should not be an issue.  
As David said, these builtins should be reserved to implement \<stdatomic.h\> and , so should never have to call them explicitly.

> or, based on the discussion between David and Richard, perhaps:
> 
> \__c11\_atomic_
> 
> to call out their close correspondance with the c11 spec.

– Jean-Daniel

---

<div class="post-metadata">

**Author:** ![Marc\_Driftmeyer](https://avatars.discourse-cdn.com/v4/letter/m/9de0a6/32.png) [@Marc\_Driftmeyer](https://discourse.llvm.org/u/Marc_Driftmeyer)\
**Post date:** [April 11, 2012, 12:47am UTC](https://discourse.llvm.org/t/rfc-atomic-support-for-gcc-4-7-compatibility/22733/16 "2012-04-11T00:47:25Z")

</div>

You folks do all the heavy lifting and thus are fully/well versed in the syntax and phonetics of the grammar you choose, but to put it bluntly if English became a chicken scratch language it never would have developed fully [though other languages would challenge that fully developed assertion on my part].

**\__clang\_atomic_** is clearly readable and discernible, and I could care less about saving a few bytes in characters. Most editors can also make custom tags that trigger the entire string with a simple combination of key-strokes for an action to be performed.

This is one of the reasons I personally have a love/hate relationship with Computer Science and another reason Mechanical Engineering is my first and more beloved degree.

It’s also another reason I was glad to work at NeXT and Apple with the knowledge that Objective-C is such a readable programming language, unlike the chicken scratch often found in C/C++.

Sincerely,

- Marc J. Driftmeyer

---

<div class="post-metadata">

**Author:** ![Seth\_Cantrell1](https://avatars.discourse-cdn.com/v4/letter/s/eb8c5e/32.png) [@Seth\_Cantrell1](https://discourse.llvm.org/u/Seth_Cantrell1)\
**Post date:** [April 11, 2012, 12:54am UTC](https://discourse.llvm.org/t/rfc-atomic-support-for-gcc-4-7-compatibility/22733/17 "2012-04-11T00:54:30Z")

</div>

Calling out the correspondence with the C11 spec with \__c11\_atomic_ does seem desirable. Also maybe it’s better for adoption by gcc as well, if they choose to add builtins that correspond to C11?

---

<div class="post-metadata">

**Author:** ![Finkel\_Hal\_J](https://avatars.discourse-cdn.com/v4/letter/f/a9adbd/32.png) [@Finkel\_Hal\_J](https://discourse.llvm.org/u/Finkel_Hal_J)\
**Post date:** [April 11, 2012, 3:44am UTC](https://discourse.llvm.org/t/rfc-atomic-support-for-gcc-4-7-compatibility/22733/18 "2012-04-11T03:44:30Z")

</div>

> Calling out the correspondence with the C11 spec with \_\_c11\_atomic\_  
> does seem desirable.

I agree. Another alternative is to just use \_\_builtin\_.

-Hal

Also maybe it's better for adoption by gcc as

---

<div class="post-metadata">

**Author:** ![Jeffrey\_Yasskin](https://avatars.discourse-cdn.com/v4/letter/j/e99b99/32.png) [@Jeffrey\_Yasskin](https://discourse.llvm.org/u/Jeffrey_Yasskin)\
**Post date:** [April 11, 2012, 6:31am UTC](https://discourse.llvm.org/t/rfc-atomic-support-for-gcc-4-7-compatibility/22733/19 "2012-04-11T06:31:20Z")

</div>

If \_\_o-\>\_\_a\_ is an \_Atomic(\_Tp), then C11 says "Loads and stores of  
objects with atomic types are done with memory\_order\_seq\_cst  
semantics." (6.2.6.1), and the simple assignment gives you the  
equivalent of atomic\_store(&\_\_o-\>\_\_a\_, \_\_d, memory\_order\_seq\_cst).

You could get the effect of atomic\_init with a memcpy, but only by  
knowing the \_Atomic(\_Tp)'s layout on the target platform.

---

<div class="post-metadata">

**Author:** ![David\_Chisnall](https://avatars.discourse-cdn.com/v4/letter/d/5fc32e/32.png) [@David\_Chisnall](https://discourse.llvm.org/u/David_Chisnall)\
**Post date:** [April 11, 2012, 9:48am UTC](https://discourse.llvm.org/t/rfc-atomic-support-for-gcc-4-7-compatibility/22733/20 "2012-04-11T09:48:51Z")

</div>

> Of course. I'd much rather you be awake when you do this. 🙂

I thought you might...

> > \_\_atomic\_init() is still required for atomic\_init() (in both C11 and C++11) - these are currently using \_\_atomic\_store, in libc++, so I'll fix them at the same time.
> 
> template \<class \_Tp\>  
> inline \_LIBCPP\_INLINE\_VISIBILITY  
> void  
> atomic\_init(atomic\<\_Tp\>\* \_\_o, \_Tp \_\_d)  
> {  
> &nbsp;&nbsp;&nbsp;\_\_o-\>\_\_a\_ = \_\_d;  
> }
> 
> Not right?

No, because assignments to \_Atomic() variables with = are atomic, with sequentially consistent semantics. This is more or less the opposite of what we want.

David

[Next page](https://discourse.llvm.org/t/rfc-atomic-support-for-gcc-4-7-compatibility/22733.md?page=2)
