public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
From: Alejandro Colomar <alx@kernel.org>
To: Amol Surati <suratiamol@gmail.com>
Cc: gcc-help@gcc.gnu.org
Subject: Re: Assignment of union containing const-qualifier member
Date: Sun, 4 Feb 2024 21:37:38 +0100	[thread overview]
Message-ID: <Zb_1mC2HnF7jCjYd@debian> (raw)
In-Reply-To: <Zb_aHb_kkhiHt1d6@debian>

[-- Attachment #1: Type: text/plain, Size: 2524 bytes --]

On Sun, Feb 04, 2024 at 07:40:23PM +0100, Alejandro Colomar wrote:
> > 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.
> 
> Modifying a union via a non-const member is fine in C, I believe.  I
> think you're creating a new object, and discarding the old one, so you
> don't need to care if there was an old object defined via a
> const-qualified type.  That is, the following code is valid C, AFAIK:
> 
> 	alx@debian:~/tmp$ cat u.c 
> 	union u {
> 		int        a;
> 		const int  b;
> 	};
> 
> 	int
> 	main(void)
> 	{
> 		union u  u = {.b = 42};
> 
> 		u.a = 7;
> 		return u.b;
> 	}
> 	alx@debian:~/tmp$ gcc-14 -Wall -Wextra u.c 
> 	alx@debian:~/tmp$ ./a.out ; echo $?
> 	7
> 	alx@debian:~/tmp$ clang-17 -Weverything u.c 
> 	alx@debian:~/tmp$ ./a.out ; echo $?
> 	7

Although I would have doubts about what happens if the union contains
an aggregate, and you modify part of it:

	union u {
		int        a[2];
		const int  b[2];
	};

	int
	main(void)
	{
		union u  u = {.b = {42, 13}};

		u.a[0] = 7;
		return u.b[0];
	}

or

	union u {
		struct {
			int        a0;
			int        a1;
		} a;
		const struct {
			const int  b0;
			const int  b1;
		} b;
	};

	int
	main(void)
	{
		union u  u = {.b = {42, 13}};

		u.a.a0 = 7;
		return u.b.b0;
	}

In these cases, we're mnodifying a const object (.b), via a non-const
lvalue (.a.a0, and .a.a1).  We're modifying it, because we keep the
original value at .b.b1, but the new one at .b.b0, so in this case we
can't say it's an entire new object.

Is this legal?  Both GCC and Clang accept it, but I have doubts.
Maybe you could warn if the program sets a union via a const member when
there are non-const members, because it seems like something wrong to
do.

But as long as you don't set the const member, you should be fine
according to ISO C.  That is, if you initialize the union via .a, then
anything is valid, as the object is defined non-const.

Have a lovely night,
Alex

-- 
<https://www.alejandro-colomar.es/>
Looking for a remote C programming job at the moment.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  reply	other threads:[~2024-02-04 20:37 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-30 21:45 Alejandro Colomar
2024-01-31 18:14 ` Alejandro Colomar
2024-02-04  7:33   ` Amol Surati
2024-02-04  8:18     ` Amol Surati
2024-02-04 18:40     ` Alejandro Colomar
2024-02-04 20:37       ` Alejandro Colomar [this message]
2024-02-07  4:13       ` Amol Surati
2024-02-07 13:29         ` Alejandro Colomar
2024-02-12 10:45           ` Amol Surati
2024-02-12 11:18             ` Amol Surati
2024-03-18  9:19             ` Alejandro Colomar
2024-03-18  9:23               ` Alejandro Colomar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Zb_1mC2HnF7jCjYd@debian \
    --to=alx@kernel.org \
    --cc=gcc-help@gcc.gnu.org \
    --cc=suratiamol@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).