[libc++] RFC: Restricting use of <atomic> in C++03 (?)

Hi All,

We need to decide if libc++ should support <atomic> in C++03. libc++
is usually considered to be "a c++11 standard library with C++03
support." Almost all C++11 library features are supported in C++03 and
supporting <atomic> would be consistent with this.

Currently the atomic header behaves weirdly. Including <atomic> in
C++03 with clang will explicitly cause a '#error <atomic> is not
implemented'. However including <atomic> in C++03 with GCC works just
fine. The reasons for this are accidental but this is how it currently
stands.

It is *trivial* to support <atomic> in C++03 for both Clang and GCC
except for one feature.
In C++03 std::atomic cannot support aggregate initialization. That
means atomics cannot be initialized using either:

    std::atomic<int> i = ATOMIC_VAR_INIT(42);
    std::atomic<int> i = { 42 }

Losing aggregate initialization means that non-local atomics can no
longer initialized during the static initialization phase of program
startup but instead during the dynamic initialization phase. This
makes defining correct atomic globals very hard. As chandlerc
previously pointed out, this is a pretty fundamental use case for
atomics.

Other than losing this feature, the rest of <atomic> works out of the
box in C++03.

Below are two options along with some of their pros and cons.

1. Allowing use of <atomic> and #undef ATOMIC_VAR_INIT in C++03.
    - Pro: Consistent with handling of other C++11 library features.
    - Pro: This will not break existing C++03 code that previously
worked with GCC.
    - Pro: Almost all of <atomic> works in C++03.
    - Con: atomics cannot be safely used during program startup.
    - Con: ATOMIC_VAR_INIT would be missing in C++03.

2. Explicitly disallow use of <atomic> in C++03 by using `#error`.
    - Con: This could possible break users who depend on atomic with
GCC in C++03.
    - Pro: This change won't break Clang users.
    - Pro: atomic is always feature complete when included.

I have no preference one way or the other but I would like a decision
to be made. Until then I do not know what to do with the <atomic>
tests.

Any input is appreciated.

/Eric

Hi All,

We need to decide if libc++ should support <atomic> in C++03. libc++
is usually considered to be "a c++11 standard library with C++03
support." Almost all C++11 library features are supported in C++03 and
supporting <atomic> would be consistent with this.

Currently the atomic header behaves weirdly. Including <atomic> in
C++03 with clang will explicitly cause a '#error <atomic> is not
implemented'. However including <atomic> in C++03 with GCC works just
fine. The reasons for this are accidental but this is how it currently
stands.

It is *trivial* to support <atomic> in C++03 for both Clang and GCC
except for one feature.
In C++03 std::atomic cannot support aggregate initialization. That
means atomics cannot be initialized using either:

    std::atomic<int> i = ATOMIC_VAR_INIT(42);
    std::atomic<int> i = { 42 }

Losing aggregate initialization means that non-local atomics can no
longer initialized during the static initialization phase of program
startup but instead during the dynamic initialization phase. This
makes defining correct atomic globals very hard. As chandlerc
previously pointed out, this is a pretty fundamental use case for
atomics.

Other than losing this feature, the rest of <atomic> works out of the
box in C++03.

Below are two options along with some of their pros and cons.

1. Allowing use of <atomic> and #undef ATOMIC_VAR_INIT in C++03.
    - Pro: Consistent with handling of other C++11 library features.
    - Pro: This will not break existing C++03 code that previously
worked with GCC.
    - Pro: Almost all of <atomic> works in C++03.
    - Con: atomics cannot be safely used during program startup.
    - Con: ATOMIC_VAR_INIT would be missing in C++03.

These cases result in build errors, rather than silent wrong behaviour, so
they don't seem especially bad. Sure, <atomic> would be less useful in
C++03, but it wouldn't be entirely useless. It would mean that you don't
get generalized constant expressions and list initialization syntax using
<atomic> in C++03, but that's true for all libc++ components, so it seems
reasonably consistent.

The only slightly inconsistent part of this approach is making
ATOMIC_VAR_INIT unavailable rather than making it work but be non-constant,
and that seems important for safety.

2. Explicitly disallow use of <atomic> in C++03 by using `#error`.
    - Con: This could possible break users who depend on atomic with
GCC in C++03.
    - Pro: This change won't break Clang users.

Does the other change break Clang users somehow?

Hi All,

We need to decide if libc++ should support <atomic> in C++03. libc++
is usually considered to be "a c++11 standard library with C++03
support." Almost all C++11 library features are supported in C++03 and
supporting <atomic> would be consistent with this.

Currently the atomic header behaves weirdly. Including <atomic> in
C++03 with clang will explicitly cause a '#error <atomic> is not
implemented'. However including <atomic> in C++03 with GCC works just
fine. The reasons for this are accidental but this is how it currently
stands.

It is *trivial* to support <atomic> in C++03 for both Clang and GCC
except for one feature.
In C++03 std::atomic cannot support aggregate initialization. That
means atomics cannot be initialized using either:

    std::atomic<int> i = ATOMIC_VAR_INIT(42);
    std::atomic<int> i = { 42 }

Losing aggregate initialization means that non-local atomics can no
longer initialized during the static initialization phase of program
startup but instead during the dynamic initialization phase. This
makes defining correct atomic globals very hard. As chandlerc
previously pointed out, this is a pretty fundamental use case for
atomics.

Other than losing this feature, the rest of <atomic> works out of the
box in C++03.

Below are two options along with some of their pros and cons.

1. Allowing use of <atomic> and #undef ATOMIC_VAR_INIT in C++03.
    - Pro: Consistent with handling of other C++11 library features.
    - Pro: This will not break existing C++03 code that previously
worked with GCC.
    - Pro: Almost all of <atomic> works in C++03.
    - Con: atomics cannot be safely used during program startup.
    - Con: ATOMIC_VAR_INIT would be missing in C++03.

These cases result in build errors, rather than silent wrong behaviour, so
they don't seem especially bad. Sure, <atomic> would be less useful in
C++03, but it wouldn't be entirely useless. It would mean that you don't get
generalized constant expressions and list initialization syntax using
<atomic> in C++03, but that's true for all libc++ components, so it seems
reasonably consistent.

The only slightly inconsistent part of this approach is making
ATOMIC_VAR_INIT unavailable rather than making it work but be non-constant,
and that seems important for safety.

2. Explicitly disallow use of <atomic> in C++03 by using `#error`.
    - Con: This could possible break users who depend on atomic with
GCC in C++03.
    - Pro: This change won't break Clang users.

Does the other change break Clang users somehow?

No it won't. I just wanted to be clear that *only* GCC users could break.