C++ Logo

liaison

Advanced search

Re: [isocpp-wg14/wg21-liaison] [SC22WG14.26035] constexpr atomic in C++ compatibility concerns

From: Billy O'Neal (VC AIR) <"Billy>
Date: Mon, 1 Jul 2024 21:56:02 +0000
Note that on MSVC atomic<3 byte struct> is 8 bytes. 🙃 I expect in a hypothetical future time when we can break ABI it will be 4 bytes (effectively matching Clang’s original behavior).

This is to preserve atomic working between ‘crt boundaries’ as when multiple C runtimes are in the process we have no means of choosing the one true owner of the external lock table.

Billy3

From: Liaison <liaison-bounces_at_[hidden]> On Behalf Of Hans Boehm via Liaison
Sent: Monday, July 1, 2024 2:43 PM
To: liaison_at_[hidden]
Cc: Hans Boehm <boehm_at_acm.org>; Hana Dusíková <hanicka_at_[hidden]>; sc22wg14_at_[hidden]
Subject: Re: [isocpp-wg14/wg21-liaison] [SC22WG14.26035] constexpr atomic in C++ compatibility concerns

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]<mailto: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]<mailto: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]<mailto: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:56:18