C++ Logo

std-proposals

Advanced search

Re: [std-proposals] [[packed]]

From: Gašper Ažman <gasper.azman_at_[hidden]>
Date: Sun, 10 Dec 2023 23:24:47 +0000
I'd like it to be trivial, not just trivially copyable.

https://godbolt.org/z/GGzEYjv6q

That said, std::start_lifetime_as and std::start_lifetime_as_array, which
are the relevant two functions here, only require trivally copyable, so
maybe that's enough.

G

On Thu, Dec 7, 2023 at 11:00 AM Lénárd Szolnoki <cpp_at_[hidden]>
wrote:

> On Thu, 2023-12-07 at 10:09 +0000, Gašper Ažman wrote:
> > The implementation is a reasonable start but unaligned<trivial> needs
> > to itself be trivial (to allow composition of structs containing
> > unaligned members inside other unaligned<> ), so it gets just a tad
> > more interesting.
>
> It is trivial, isn't it?
>
> https://godbolt.org/z/ddT6Mb65n
>
> Specifically it needs to be trivially copyable.
>
> >
> > On Thu, Dec 7, 2023, 08:01 Lénárd Szolnoki via Std-Proposals
> > <std-proposals_at_[hidden]> wrote:
> > > On Wed, 2023-12-06 at 17:01 +0000, Frederick Virchanza Gotham via
> > > Std-
> > > Proposals wrote:
> > > > On Wed, Dec 6, 2023 at 4:52 PM Gašper Ažman wrote:
> > > > >
> > > > > ++ for unaligned<trivial>
> > > >
> > > >
> > > > So how would "std::unaligned<Trivial>" work? Would it lack tail
> > > > padding? Or would it lack tail padding and also lack padding
> > > > between
> > > > members?
> > >
> > > std::unaligned would be applied to the members, not the enclosing
> > > class, like so:
> > >
> > > struct Monkey {
> > > std::unaligned<long> l;
> > > char ch;
> > > };
> > > static_assert(sizeof(Monkey) == sizeof(long) + sizeof(char));
> > >
> > > std::unaligned could be implemented something like this:
> > >
> > > template <typename T, std::size_t alignment = 1>
> > > requires (std::popcount(alignment) == 1)
> > > class unaligned {
> > > static_assert(std::is_trivially_copyable_v<T>);
> > >
> > > using storage_t = std::array<std::byte, sizeof(T)>;
> > > alignas(alignment) storage_t m_storage;
> > >
> > > public:
> > > constexpr unaligned(T t) noexcept
> > > : m_storage(std::bit_cast<storage_t>(t))
> > > {}
> > >
> > > constexpr operator T() noexcept {
> > > return std::bit_cast<T>(m_storage);
> > > }
> > > };
> > >
> > > You also identified the problem of taking address of packed members
> > > and
> > > the potential need for special treatment of them in the language.
> > > If
> > > implemented like above then you don't need special treatment in the
> > > language, you can't take the address and get a `long *` out of an
> > > unaligned<long>.
> > >
> > > >
> > > > So if I have a trivial standard-layout struct as follows:
> > > >
> > > > struct Monkey {
> > > > long unsigned a;
> > > > char b;
> > > > // padding here?
> > > > long double c;
> > > > char d;
> > > > // padding here?
> > > > float e;
> > > > char f;
> > > > // padding here?
> > > > };
> > > >
> > > > Then what will std::unaligned<Monkey> do? Will it take out just
> > > > the
> > > > tail padding, or will it take out the 3 pieces of padding?
> > >
>
>

Received on 2023-12-10 23:25:00