This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Possible invalid code - GCC 4.8/5.1.
- From: Jonathan Wakely <jwakely dot gcc at gmail dot com>
- To: Krzysztof HaÅasa <khalasa at piap dot pl>
- Cc: "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>
- Date: Wed, 17 Jun 2015 09:52:02 +0100
- Subject: Re: Possible invalid code - GCC 4.8/5.1.
- Authentication-results: sourceware.org; auth=none
- References: <m3d20uu4vj dot fsf at t19 dot piap dot pl>
On 17 June 2015 at 09:16, Krzysztof HaÅasa <khalasa@piap.pl> wrote:
> Hi,
>
> I wonder if the following is a bug:
>
> #include <stdio.h>
>
> int main(void)
> {
> struct str {
> struct a {
> int a1, a2;
> } a;
> };
>
> struct str src = {.a = {.a1 = 1, .a2 = 2}};
>
> struct str dest = {.a = src.a, .a.a2 = 3};
>
> printf("src: %u %u, dest: %u %u\n", src.a.a1, src.a.a2, dest.a.a1, dest.a.a2);
> return 0;
> }
>
> $ gcc -W -Wall test.c -o test
> $ ./test
> src: 1 2, dest: 0 3
>
> GCC 4.8.4 (ARM), Red Hat 4.9.2-6, Red Hat 5.1.1-1 (x86-64 Fedora 21 and 22).
>
> Should I file a bz report?
N.B. mails about bug are almost never appropriate on this mailing
list, either ask on the gcc-help mailing list or file a bugzilla,
don't ask "should I file a bugzilla" on this list.
This is the correct behaviour.
When the initializer .a.a2 = 3 is processed the current object is the
whole of dest, so all the other members of the current object are set
to zero, which overrides the values set by the earlier .a = src.a
initializer.
It would be nice if the compiler warned you about this.
> BTW changing the initializer from ".a = src.a" to ".a = {1, 2}" produces
> the expected result:
>
> $ gcc -W -Wall test.c -o test
> test.c: In function âmainâ:
> test.c:13:9: warning: initialized field overwritten [-Woverride-init]
> struct str dest = {.a = {1, 2}, .a.a2 = 3};
> ^
> test.c:13:9: warning: (near initialization for âdest.a.a2â) [-Woverride-init]
>
> $ ./test
> src: 1 2, dest: 1 3
I believe this is also correct behaviour.
The brace-enclosed initializer list {1, 2} makes .a the "current
object", then the elements make .a.a1 and .a.a2 the current object in
turn. When the .a.a2 = 3 initializer is processed .a.a2 is the current
object, and that object has no other members, so nothing else is set
to zero.