Date: Mon, 1 Jul 2024 14:43:00 -0700
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).
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
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).
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
Received on 2024-07-01 21:43:20