Re: Assignment of union containing const-qualifier member

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, 4 Feb 2024 at 13:03, Amol Surati <suratiamol@xxxxxxxxx> wrote:
>
> On Wed, 31 Jan 2024 at 23:46, Alejandro Colomar via Gcc-help
> <gcc-help@xxxxxxxxxxx> wrote:
> >
> > On Tue, Jan 30, 2024 at 10:45:11PM +0100, Alejandro Colomar wrote:
> > > Hi,
> > >
>
> [ ... ]
>
> > structure, that doesn't help.  memcpy(3) does help, but it looses all
> > type safety.
> >
> > Maybe this could be allowed as an extension.  Any thoughts?
> >
>
> Does it make sense to propose that, if the first top-level member of a
> union is completely (i.e. recursively) writable, then a non-const union
> object as a whole is writable? If so, then, for union objects a and b of
> a union that has such const members, a = b can be expected to not
> raise errors about const-correctness.

This doesn't look okay- what if the last written-to member was not the
first member of the union? The assignment can either copy the full
size of the union (i.e. sizeof (b)) or copy just the member that was
last written to within b. The latter requires the compiler to maintain
an 'active' member of unions, which I believe isn't expected from the
compilers.

I believe the compiler performs an assignment a=b through
memcpy (or through statements that have similar effects as that of
memcpy) that, as you noticed, ignores type-safety. It may be because
of such obstacles that the presence of a const member in the union
prevents a union object from being a modifiable lvalue.

>
> It seems that a union only provides a view of the object. The union
> object doesn't automatically become const qualified if a member
> of the union is const-qualified. This seems to be the reason v.w = u.w
> works; otherwise, that modification can also be viewed as the
> modification of an object (v.r) defined with a const-qualified type through
> the use of an lvalue (v.w) with non-const-qualified type - something that's
> forbidden by the std.
>
> More towards the use of the string as described:
> If there are multiple such union objects that point to the same string,
> and if a piece of code decides to modify the string, other consumers of
> this string remain unaware of the modification, unless they check for it,
> for e.g., by keeping a copy, calc. hash, etc., to ensure that the string was
> indeed not silently modified behind their backs.
>
> I think it is better to have a 'class' and associated APIs.
> See [1], for e.g., or the implementation of c++ std::string.
>
> The ownership of an object of such a class can be passed by passing
> a non-const pointer to the object.
>
> Functions that are not supposed to own the object can be passed a
> const pointer. Despite that, if such functions need to modify it for local
> needs, they can create a copy to work with.
>
> One can additionally maintain a ref-count on the char pointer, to avoid
> having to unnecessarily copy a string if it is going to be placed in several
> stay-resident-after-return data-structures.
>
> -Amol
>
> [1] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3210.pdf
>
> > Cheers,
> > Alex
> >
> > --
> > <https://www.alejandro-colomar.es/>
> > Looking for a remote C programming job at the moment.



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux