public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Union initialization semantics
@ 2024-06-19 10:57 Alexander Monakov
  2024-06-19 12:59 ` Jonathan Wakely
  0 siblings, 1 reply; 3+ messages in thread
From: Alexander Monakov @ 2024-06-19 10:57 UTC (permalink / raw)
  To: gcc

Hello,

I vaguely remember there was a recent, maybe within last two months, discussion
about semantics of union initialization where sizeof(first member) is less than
sizeof(union). The question was whether it's okay to initialize just that first
member and leave garbage bits in the other, larger, members of the union, like
in this example:

union A {
    char a;
    long : 0;
};

void fn(void *);

void my(void)
{
    union A a = { 0 };
    fn(&a);
}

(except in my example there's no other named member, but I think the example
in that discussion was less contrived)

Perhaps somebody remembers where it was (I'm thinking Bugzilla) and could point
me to it? My attempts to search for it aren't turning anything up so far.

If someone knows what semantics GCC implements, that also would be welcome.

Thank you.
Alexander

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Union initialization semantics
  2024-06-19 10:57 Union initialization semantics Alexander Monakov
@ 2024-06-19 12:59 ` Jonathan Wakely
  2024-06-19 19:02   ` Martin Uecker
  0 siblings, 1 reply; 3+ messages in thread
From: Jonathan Wakely @ 2024-06-19 12:59 UTC (permalink / raw)
  To: Alexander Monakov; +Cc: gcc

On Wed, 19 Jun 2024 at 11:57, Alexander Monakov <amonakov@ispras.ru> wrote:
>
> Hello,
>
> I vaguely remember there was a recent, maybe within last two months, discussion
> about semantics of union initialization where sizeof(first member) is less than
> sizeof(union). The question was whether it's okay to initialize just that first
> member and leave garbage bits in the other, larger, members of the union, like
> in this example:
>
> union A {
>     char a;
>     long : 0;
> };
>
> void fn(void *);
>
> void my(void)
> {
>     union A a = { 0 };
>     fn(&a);
> }
>
> (except in my example there's no other named member, but I think the example
> in that discussion was less contrived)
>
> Perhaps somebody remembers where it was (I'm thinking Bugzilla) and could point
> me to it? My attempts to search for it aren't turning anything up so far.

Somebody asked about this internally at Red Hat recently, and I
responded with this quote from C17 6.2.6.1 p7:
"When a value is stored in a member of an object of union type, the
bytes of the object representation that do not correspond to that
member but do correspond to other members take unspecified values. "

This looks related too:
https://discourse.llvm.org/t/union-initialization-and-aliasing-clang-18-seems-to-miscompile-musl/77724/3
They don't seem to have found the quote above though.

I think it got reported to GCC's bugzilla too, I'll see if I can find it again.

> If someone knows what semantics GCC implements, that also would be welcome.

GCC seems to initialize the trailing bits, unnecessarily.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Union initialization semantics
  2024-06-19 12:59 ` Jonathan Wakely
@ 2024-06-19 19:02   ` Martin Uecker
  0 siblings, 0 replies; 3+ messages in thread
From: Martin Uecker @ 2024-06-19 19:02 UTC (permalink / raw)
  To: Jonathan Wakely, Alexander Monakov; +Cc: gcc

Am Mittwoch, dem 19.06.2024 um 13:59 +0100 schrieb Jonathan Wakely via Gcc:
> On Wed, 19 Jun 2024 at 11:57, Alexander Monakov <amonakov@ispras.ru> wrote:
> > 
> > Hello,
> > 
> > I vaguely remember there was a recent, maybe within last two months, discussion
> > about semantics of union initialization where sizeof(first member) is less than
> > sizeof(union). The question was whether it's okay to initialize just that first
> > member and leave garbage bits in the other, larger, members of the union, like
> > in this example:
> > 
> > union A {
> >     char a;
> >     long : 0;
> > };
> > 
> > void fn(void *);
> > 
> > void my(void)
> > {
> >     union A a = { 0 };
> >     fn(&a);
> > }
> > 
> > (except in my example there's no other named member, but I think the example
> > in that discussion was less contrived)
> > 
> > Perhaps somebody remembers where it was (I'm thinking Bugzilla) and could point
> > me to it? My attempts to search for it aren't turning anything up so far.
> 
> Somebody asked about this internally at Red Hat recently, and I
> responded with this quote from C17 6.2.6.1 p7:
> "When a value is stored in a member of an object of union type, the
> bytes of the object representation that do not correspond to that
> member but do correspond to other members take unspecified values. "
> 
> This looks related too:
> https://discourse.llvm.org/t/union-initialization-and-aliasing-clang-18-seems-to-miscompile-musl/77724/3
> They don't seem to have found the quote above though.
> 
> I think it got reported to GCC's bugzilla too, I'll see if I can find it again.
> 
> > If someone knows what semantics GCC implements, that also would be welcome.
> 
> GCC seems to initialize the trailing bits, unnecessarily.

Note that C23 will require the padding bits to be initialized with zero
for default initialization {}.

Martin




^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-06-19 19:03 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-06-19 10:57 Union initialization semantics Alexander Monakov
2024-06-19 12:59 ` Jonathan Wakely
2024-06-19 19:02   ` Martin Uecker

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).