Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date: Fri, 7 Jul 2023 16:46:45 +0200
From: Markus Wichmann <nullplan@....net>
To: musl@...ts.openwall.com
Subject: Re: [C23 string conversion 1/2] C23: implement the c8rtomb
 and mbrtoc8 functions

Am Mon, Jul 03, 2023 at 07:37:44AM +0600 schrieb NRK:
> On Sun, Jun 25, 2023 at 01:26:20PM -0400, Rich Felker wrote:
> > A cleaner approach might be a union where the presence of the unsigned
> > union member yields the alignment.
>
> Slightly off-topic, but do you know if this is a standardized guarantee
> or not?  While I'm aware that this works in practice - sometime ago I
> was looking into the standard (c99 IIRC) to see if there's anything that
> actually guarantees that or not and couldn't find anything concrete.
>
> - NRK

So this question was rolling around in my head for a while, and I
decided to finally look it up. And found something.

Basically, I wondered how the behavior could possibly be otherwise. In
this case, how could a union possibly have a smaller alignment
requirement that one of its members? This cannot work with just special
handling for union members, since you can create a pointer to the union
member, and then access to the pointer must work correctly, so the
pointer must be correctly aligned.

The only way I could think of would be to have dynamic padding at the
start of the union. Then you could have a union with smaller alignment
than one of its members, although the offset of that member would not be
a constant. Is that allowed?

Grepping through the standards draft (n3096 in this case) I first found
6.5.8.6, which states, among other things:

| All pointers to members of the same union object compare equal.

Already the alignment thing has been encoded here: If you have a union,
and it contains an unsigned and something else, the pointer to the
unsigned must be aligned according to the requirement for unsigned (else
it would not be a requirement). But then all other members must also be
at least as aligned as the unsigned.

Then I got to 6.7.2.1.18, which states, among other things

| A pointer to a union object, suitably converted, points to each of its
| members. [...] There may be unnamed padding at the end of a union
| object, but not at its beginning.

And there you have it. There can also be no padding at the start. If I
dug further, I would probably find that the layout of a union can also
not change dynamically, but I shall leave it at that.

Basically, ABIs only have the choice to make unions have the maximum
alignment of any of its members, or else always have unions have the
maximum alignment used on the platform. In any case, a union containing
an unsigned must be at least as aligned as the unsigned.

HTH,
Markus

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.