Arthur,

Yes, at least I was envisioning it to work akin to std::atomic<T> - with a load and a store, and nothing else. It's just a veneer over a char[] with typed fetch/store so that you don't lose the type information while passing it to things, but otherwise _IT IS NOT A T_, you can't form a T& or a T* from it, etc.

On Sun, Dec 10, 2023 at 3:00 PM Arthur O'Dwyer via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
On Sat, Dec 9, 2023 at 7:20 PM Lénárd Szolnoki via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
On Sat, 2023-12-09 at 22:14 +0000, Frederick Virchanza Gotham via Std-Proposals wrote:
> On Saturday, December 9, 2023, Frederick Virchanza Gotham wrote:
> >
> > In both of these use cases, I'd much prefer if we could do the
> > following:
> >
> >     struct TokenInfo {
> >         long unsigned a;
> >         char b;
> >         long unsigned c;
> >         char d;
> >     };
> >
> >     typedef struct TokenInfo [[packed]] TicketInfo;
> >
> > So now 'TicketInfo' is a packed form of the 'TokenInfo' struct.

An attribute is the wrong tool for this as it is ignorable. Maybe once
metaclasses land then it could be feasible, and still a pure library
implementation.

Actually, we were just arguing about this (basically because different people have vastly different ideas of what "ignorable" was ever supposed to mean in the first place) over in this CWG reflector thread: https://lists.isocpp.org/core/2023/11/15103.php  It turns out that struct layout is pretty much the most implementation-defined thing in the world, and thus "ignorable" by (some) definition — because an implementation can just say "This attribute does nothing on my platform's ABI" and that's okay. (MSVC does this with [[no_unique_address]]. That's extremely low QoI, but there's nothing wrong with it from the paper standard's point of view.)
So [[packed]] — that is, standardizing the existing practice of __attribute__((packed)) — would be totally fine.

However, I don't think Frederick has realized yet that his "packed TokenInfo" (where the attribute cracks open the curly braces and applies itself to all subobjects recursively) is-not-a kind of "TokenInfo". There are things you can do with a "TokenInfo" which you physically cannot do with such a "packed TokenInfo." One example is "fetch its `c` member with an aligned load instruction" (because the packed TokenInfo's `c` is misaligned). Another example is "evaluate `&p->c` and have it give you a pointer of type `long unsigned*`" (because the language assumes that it's always safe to load from a `long unsigned*` using an aligned load instruction).
Clang and GCC just make this a warning: https://godbolt.org/z/vGGWYMq64
IIRC, Green Hills provides `__packed` as a type qualifier (like `const` and `volatile`), where taking the address of a `__packed int pi` just gives you a `__packed int *ppi`, and the compiler understands that loading from `*ppi` will require a misaligned load.

I don't fully see what people are envisioning even with this `std::unaligned<T>` syntax. I mean, you could make it work like `std::atomic<T>`, and maybe that's good enough, and what people are expecting —
    std::unaligned<int> ai = 0;
    int x = ai.load();  // copy out the value
but you certainly couldn't make it work like `T` itself —
    std::unaligned<int> ai = 0;
    int *p = &ai.value();  // point to the held value? no! physically impossible!
    std::unaligned<MyTrivial> at;
    at->my_member_function();  // call a member function on the held value? no! physically impossible!
(Did/does Green Hills allow you to write a member function `void my_member_function() __packed { ~~~ }` receiving a __packed-qualified this pointer? I don't recall. Probably not. But it would be consistent.)

–Arthur
--
Std-Proposals mailing list
Std-Proposals@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals