Date: Tue, 2 Jul 2024 17:08:17 -0700
On Mon, 1 Jul 2024 at 14:43, Hans Boehm via Liaison <
liaison_at_[hidden]> wrote:
> My impression is that the clang vs gcc atomics compatibility issues have
> improved, probably since that bug was filed. See also wg21.link/p0943,
> which we adopted long ago, but after that bug was filed.
>
> Gcc and clang did not agree on my preferred solution, but they do now seem
> to agree. In particular, they both do not pad atomic<3_byte_struct> to 4
> bytes. To be really useful, in almost all cases programmers should pad such
> structs to a power of 2. Though this isn't ideal, at least IMO, it seems
> like something we can live with. Properly written code shouldn't fail if
> you mix compilers, but if you use atomic<3_byte_struct> it may run much
> slower than you expected (and use less memory).
>
I don't think much has changed here. Your test below is comparing clang
libstdc++ against GCC libstdc++, and they always agreed because libstdc++'s
<atomic> does the padding itself in the header. See the first comment on
https://github.com/llvm/llvm-project/issues/26836 for a (now eight years
old) description of the problem, that I think is still accurate today.
GCC and Clang folks asked the psABI maintainers
<https://groups.google.com/g/ia32-abi/c/Tlu6Hs-ohPY> to do something about
it, and it seems like they didn't. So we're kind of stuck. No-one wants to
break their compiler's ABI without an official decision from the owners of
the ABI, and we don't have an official decision. Maybe someone could try to
resurrect that thread.
> On my workstation:
>
> hboehm_at_hboehm2:~/tests$ cat align3.cpp
> #include <stdio.h>
> #include <atomic>
>
> typedef struct{char x[3];} c3;
> typedef struct{char x[4];} c4;
> typedef struct{char x[5];} c5;
> typedef struct{char x[8];} c8;
> typedef struct{char x[9];} c9;
> typedef struct{char x[16];} c16;
> typedef struct{char x[17];} c17;
> typedef struct{char x[32];} c32;
>
>
> int main() {
> printf("%zu %zu\n", alignof(double), alignof(std::atomic<double>));
> printf("%zu %zu\n", alignof(long long), alignof(std::atomic<long long>));
> printf("%zu %zu\n", alignof(c3), alignof(std::atomic<c3>));
> printf("%zu %zu\n", alignof(c4), alignof(std::atomic<c4>));
> printf("%zu %zu\n", alignof(c5), alignof(std::atomic<c5>));
> printf("%zu %zu\n", alignof(c8), alignof(std::atomic<c8>));
> printf("%zu %zu\n", alignof(c9), alignof(std::atomic<c9>));
> printf("%zu %zu\n", alignof(c16), alignof(std::atomic<c16>));
> printf("%zu %zu\n", alignof(c17), alignof(std::atomic<c17>));
> printf("%zu %zu\n", alignof(c32), alignof(std::atomic<c32>));
> return 0;
> }
>
>
> hboehm_at_hboehm2:~/tests$ clang++ align3.cpp
> hboehm_at_hboehm2:~/tests$ ./a.out
> 8 8
> 8 8
> 1 1
> 1 4
> 1 1
> 1 8
> 1 1
> 1 16
> 1 1
> 1 1
> hboehm_at_hboehm2:~/tests$ g++ align3.cpp
> hboehm_at_hboehm2:~/tests$ ./a.out
> 8 8
> 8 8
> 1 1
> 1 4
> 1 1
> 1 8
> 1 1
> 1 16
> 1 1
> 1 1
> hboehm_at_hboehm2:~/tests$ g++ --version
> g++ (Debian 13.2.0-13) 13.2.0
> ...
>
> hboehm_at_hboehm2:~/tests$ clang++ --version
> Debian clang version 16.0.6 (20+build1)
> Target: x86_64-pc-linux-gnu
> ...
>
> On Thu, Jun 27, 2024 at 11:05 AM Martin Uecker via Liaison <
> liaison_at_[hidden]> wrote:
> >
> > Am Donnerstag, dem 27.06.2024 um 19:28 +0300 schrieb Ville Voutilainen
> via Liaison:
> > > On Thu, 27 Jun 2024 at 00:02, Niall Douglas <s_sourceforge_at_[hidden]>
> wrote:
> > > > We have layout compatibility between `_Atomic` and its equivalent
> > > > `std::atomic<>`
> > >
> > > I don't think we actually do. Or, quoth a vendor, "No. It's qoi and
> > > GCC fails at it in some cases".
> >
> > There is an incompatibility between Clang and GCC and
> > related C++ libraries on the same architecture:
> >
> > https://github.com/llvm/llvm-project/issues/26836
> >
> > >
> > > > and in real world code in a mixed C and C++ codebase
> > > > people rely on the above functions being interchangeable when
> operating
> > > > on the same memory i.e. a header file might declare a struct member
> as
> > > > `std::atomic` if `__cplusplus`, and `_Atomic` if not.
> > >
> > > Right, but making those functions constexpr in C++ doesn't change the
> layout
> > > of anything, and it doesn't change the runtime behavior of anything,
> > > so the functions remain interoperable on platforms where they
> > > are interoperable to begin with.
> >
> > Yes, this change seems unproblematic.
> >
> > Martin
> >
> >
> >
> > _______________________________________________
> > Liaison mailing list
> > Liaison_at_[hidden]
> > Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/liaison
> > Link to this post: http://lists.isocpp.org/liaison/2024/06/1448.php
> _______________________________________________
> Liaison mailing list
> Liaison_at_[hidden]
> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/liaison
> Searchable archives: http://lists.isocpp.org/liaison/2024/07/index.php
>
liaison_at_[hidden]> wrote:
> My impression is that the clang vs gcc atomics compatibility issues have
> improved, probably since that bug was filed. See also wg21.link/p0943,
> which we adopted long ago, but after that bug was filed.
>
> Gcc and clang did not agree on my preferred solution, but they do now seem
> to agree. In particular, they both do not pad atomic<3_byte_struct> to 4
> bytes. To be really useful, in almost all cases programmers should pad such
> structs to a power of 2. Though this isn't ideal, at least IMO, it seems
> like something we can live with. Properly written code shouldn't fail if
> you mix compilers, but if you use atomic<3_byte_struct> it may run much
> slower than you expected (and use less memory).
>
I don't think much has changed here. Your test below is comparing clang
libstdc++ against GCC libstdc++, and they always agreed because libstdc++'s
<atomic> does the padding itself in the header. See the first comment on
https://github.com/llvm/llvm-project/issues/26836 for a (now eight years
old) description of the problem, that I think is still accurate today.
GCC and Clang folks asked the psABI maintainers
<https://groups.google.com/g/ia32-abi/c/Tlu6Hs-ohPY> to do something about
it, and it seems like they didn't. So we're kind of stuck. No-one wants to
break their compiler's ABI without an official decision from the owners of
the ABI, and we don't have an official decision. Maybe someone could try to
resurrect that thread.
> On my workstation:
>
> hboehm_at_hboehm2:~/tests$ cat align3.cpp
> #include <stdio.h>
> #include <atomic>
>
> typedef struct{char x[3];} c3;
> typedef struct{char x[4];} c4;
> typedef struct{char x[5];} c5;
> typedef struct{char x[8];} c8;
> typedef struct{char x[9];} c9;
> typedef struct{char x[16];} c16;
> typedef struct{char x[17];} c17;
> typedef struct{char x[32];} c32;
>
>
> int main() {
> printf("%zu %zu\n", alignof(double), alignof(std::atomic<double>));
> printf("%zu %zu\n", alignof(long long), alignof(std::atomic<long long>));
> printf("%zu %zu\n", alignof(c3), alignof(std::atomic<c3>));
> printf("%zu %zu\n", alignof(c4), alignof(std::atomic<c4>));
> printf("%zu %zu\n", alignof(c5), alignof(std::atomic<c5>));
> printf("%zu %zu\n", alignof(c8), alignof(std::atomic<c8>));
> printf("%zu %zu\n", alignof(c9), alignof(std::atomic<c9>));
> printf("%zu %zu\n", alignof(c16), alignof(std::atomic<c16>));
> printf("%zu %zu\n", alignof(c17), alignof(std::atomic<c17>));
> printf("%zu %zu\n", alignof(c32), alignof(std::atomic<c32>));
> return 0;
> }
>
>
> hboehm_at_hboehm2:~/tests$ clang++ align3.cpp
> hboehm_at_hboehm2:~/tests$ ./a.out
> 8 8
> 8 8
> 1 1
> 1 4
> 1 1
> 1 8
> 1 1
> 1 16
> 1 1
> 1 1
> hboehm_at_hboehm2:~/tests$ g++ align3.cpp
> hboehm_at_hboehm2:~/tests$ ./a.out
> 8 8
> 8 8
> 1 1
> 1 4
> 1 1
> 1 8
> 1 1
> 1 16
> 1 1
> 1 1
> hboehm_at_hboehm2:~/tests$ g++ --version
> g++ (Debian 13.2.0-13) 13.2.0
> ...
>
> hboehm_at_hboehm2:~/tests$ clang++ --version
> Debian clang version 16.0.6 (20+build1)
> Target: x86_64-pc-linux-gnu
> ...
>
> On Thu, Jun 27, 2024 at 11:05 AM Martin Uecker via Liaison <
> liaison_at_[hidden]> wrote:
> >
> > Am Donnerstag, dem 27.06.2024 um 19:28 +0300 schrieb Ville Voutilainen
> via Liaison:
> > > On Thu, 27 Jun 2024 at 00:02, Niall Douglas <s_sourceforge_at_[hidden]>
> wrote:
> > > > We have layout compatibility between `_Atomic` and its equivalent
> > > > `std::atomic<>`
> > >
> > > I don't think we actually do. Or, quoth a vendor, "No. It's qoi and
> > > GCC fails at it in some cases".
> >
> > There is an incompatibility between Clang and GCC and
> > related C++ libraries on the same architecture:
> >
> > https://github.com/llvm/llvm-project/issues/26836
> >
> > >
> > > > and in real world code in a mixed C and C++ codebase
> > > > people rely on the above functions being interchangeable when
> operating
> > > > on the same memory i.e. a header file might declare a struct member
> as
> > > > `std::atomic` if `__cplusplus`, and `_Atomic` if not.
> > >
> > > Right, but making those functions constexpr in C++ doesn't change the
> layout
> > > of anything, and it doesn't change the runtime behavior of anything,
> > > so the functions remain interoperable on platforms where they
> > > are interoperable to begin with.
> >
> > Yes, this change seems unproblematic.
> >
> > Martin
> >
> >
> >
> > _______________________________________________
> > Liaison mailing list
> > Liaison_at_[hidden]
> > Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/liaison
> > Link to this post: http://lists.isocpp.org/liaison/2024/06/1448.php
> _______________________________________________
> Liaison mailing list
> Liaison_at_[hidden]
> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/liaison
> Searchable archives: http://lists.isocpp.org/liaison/2024/07/index.php
>
Received on 2024-07-03 00:08:32