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) : < 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 -- Looking for a remote C programming job at the moment.