On Mon, Mar 18, 2024 at 12:56 PM Martin Uecker <uec...@tugraz.at> wrote:
>
> Am Montag, dem 18.03.2024 um 11:55 +0100 schrieb Martin Uecker:
> > Am Montag, dem 18.03.2024 um 09:26 +0100 schrieb Richard Biener:
> > > On Mon, Mar 18, 2024 at 8:03 AM Martin Uecker <uec...@tugraz.at> wrote:
> > >
> >
> > >
> > > Let me give you an complication example made valid in C++:
> > >
> > > struct B { float x; float y; };
> > > struct X { int n; char buf[8]; } x, y;
> > >
> > > void foo(struct B *b)
> > > {
> > >   memcpy (x.buf, b, sizeof (struct B)); // in C++:  new (x.buf) B (*b);
> >
> > Let's make it an explicit store for the moment
> > (should not make a difference though):
> >
> >     *(struct B*)x.buf = *b;
> >
> > >   y = x; // (*)
> > > }
> > >
> > > What's the effective type of 'x' in the 'y = x' copy?
> >
> > Good point. The existing wording would take the declared
> > type of x as the effective type, but this may not be
> > what you are interested in. Let's assume that x has no declared
> > type but that it had effective type struct X before the
> > store to x.buf (because of an even earlier store to
> > x with type struct X).
> >
> > There is a general question how stores to subobjects
> > affect effective types and I do not think this is clear
> > even before this proposed change.
>
> Actually, I think this is not allowed because:
>
> "An object shall have its stored value accessed only by an
> lvalue expression that has one of the following types:
>
> — a type compatible with the effective type of the object,
> ...
> — an aggregate or union type that includes one of the
> aforementioned types among its members (including,
> recursively, a member of a subaggregate or contained union), or
>
> — a character type."
>
> ... and we would need to move "a character type" above
> in the list to make it defined.

So after

*(struct B*)x.buf = *b;

'x' cannot be used to access itself?  In particular also
an access to 'x.n' is affected by this?

You are right that the current wording of the standard doesn't
clarify any of this but this kind of storage abstraction is used
commonly in the embedded world when there's no runtime
library providing allocation.  And you said you want to make
the standard closer to implementation practice ...

Elsewhere when doing 'y = x' people refer to the wording that
aggregates are copied elementwise but it's not specified how
those elementwise accesses work - the lvalues are still of type
X here or are new lvalues implicitly formed and fall under the
other wordings?  Can I thus form an effective type of X by
storing it's subobjects at respective offsets (ignoring padding,
for example) and can I then use an lvalue of type 'X' to access
the whole aggregate?

Richard.

> Martin
>
>

Reply via email to