Assignment of union containing const-qualifier member

Alejandro Colomar alx@kernel.org
Wed Jan 31 18:14:14 GMT 2024


On Tue, Jan 30, 2024 at 10:45:11PM +0100, Alejandro Colomar wrote:
> Hi,
> 
> I'm trying to do something like the following:
> 
> 	$ cat const.c 
> 	union u {
> 		int        a;
> 		const int  b;
> 	};
> 
> 	int
> 	main(void)
> 	{
> 		union u  u, v;
> 
> 		u.a = 42;
> 		v = u;
> 	}
> 	$ cc -Wall -Wextra const.c 
> 	const.c: In function ‘main’:
> 	const.c:12:11: error: assignment of read-only variable ‘v’
> 	   12 |         v = u;
> 	      |           ^
> 	const.c:9:21: warning: variable ‘v’ set but not used [-Wunused-but-set-variable]
> 	    9 |         union u  u, v;
> 	      |                     ^
> 
> The actual data I'm using is not just an int, but that serves to
> reproduce the problem easily.  In reality, the union is more like this:
> 
> 	struct rstr {
> 	    const size_t       length;
> 	    const char *const  start;
> 	};
> 
> 	union str {
> 	    struct {
> 		size_t         length;
> 		char           *start;
> 	    } w;
> 	    struct rstr        r;
> 	};
> 
> I don't see anywhere in C11 that makes this a constraint violation, and

Ahh, I didn't find it.  It's specified undex 6.3 (Conversions),
6.3.2.1 (Lvalues, arrays, and function designators)
<http://port70.net/~nsz/c/c11/n1570.html#6.3.2.1>:

< A modifiable lvalue is an lvalue that does not have array type, does
< not have an incomplete type, does not have a const- qualified type,
< and if it is a structure or union, does not have any member
< (including, recursively, any member or element of all contained
< aggregates or unions) with a const- qualified type.

I'm wondering if this is a bit conservative, and a union like this could
be a modifiable lvalue.  I find it useful, since it allows inheriting a
non-modifiable version of the string which cannot be made modifiable
again, but would let you edit the string as long as you keep the union.

I added the named member 'w' to allow copying v.w = u.w, but when the
union is part of a larger structure and I need to copy the entire
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?

Cheers,
Alex

-- 
<https://www.alejandro-colomar.es/>
Looking for a remote C programming job at the moment.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/gcc-help/attachments/20240131/0487bcfa/attachment.sig>


More information about the Gcc-help mailing list