[libcxx-commits] [libcxx] [libc++] Ensure that `std::expected` has no tail padding (PR #69673)

via libcxx-commits libcxx-commits at lists.llvm.org
Fri Oct 20 11:29:38 PDT 2023


Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>
Message-ID:
In-Reply-To: <llvm/llvm-project/pull/69673/libcxx at github.com>


huixie90 wrote:

I had more thought about it and still a bit unsure about manually adding `char` arrays as paddings.

Imagine one day we have `std::atomic<std::expected<int, int>>` (today it is not working because `std::expected<int,int>::operator=(const std::expected&)` is not trivial, but maybe one day in the future standard it could be made trivial). `atomic::compare_exchange_weak` is going to do the memory comparison (instead of `==`). As per P0528R3 (merged in c++20), the implementation needs to make objects with padding work. If we don't have these `char` arrays, if we implement the paper and it should just work but with `char` arrays, these bytes are no longer considered as padding and `compare_exchange_week` needs to compare these bytes too, which could be problematic.

Although this is a hypothetical problem which does not exist yet, but things like this could exist somewhere and we are just not aware of.

Had discussion with Louis today and he had an idea like this

```
template <class T, class U>
struct compact_pair{
    [[no_unique_address]] T t;
    [[no_unique_address]] U u;
};

template <class T, class U>
struct expected{

    union union_t{
        [[no_unique_address]] T t;
        [[no_unique_address]] U u;
    };

    compact_pair<union_t, bool> compact_pair_;
};

static_assert(sizeof(std::optional<int>) == 8);
static_assert(sizeof(expected<std::optional<int>, int>) == 8);
static_assert(sizeof(expected<expected<std::optional<int>, int>, int>) == 12);
```
 This way we can achieve `has_value` can be packed into `T`'s tail padding, and `expected`'s tail padding won't be used by anyone else

https://github.com/llvm/llvm-project/pull/69673


More information about the libcxx-commits mailing list