C++ Logo

std-proposals

Advanced search

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

From: Lénárd Szolnoki <cpp_at_[hidden]>
Date: Thu, 07 Dec 2023 11:00:27 +0000
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-07 11:00:32