This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PR c++/78572] handle array self references in intializers


On 12/20/2016 11:48 AM, Nathan Sidwell wrote:
On 12/20/2016 11:25 AM, Aldy Hernandez wrote:
The problem in this PR is that we're trying to initialize an array with
members of itself:

Jakub has even gone further to show that for the following:

    ... = { array[3]=5, array[7]=3, array[7]=8, array[7] = 9 };

things get even worse, because we generate code to write twice into [3]:

    {[3]=5, [0]=5, [7]=9, [1]=3, [2]=8, [3]=9}

I looked at this a couple of weeks ago, and got confused.  It wasn't
very clear to me how the side-effect assignments interact with any
implict zero assignments.  (Especially if one then tries to support
C-style designated initializers).

IIUC the side effects of an initializer are evaluated before the storage
of the initializer itself (separated by a sequence point).  further it
seems that default zero initialization of non-explicitly initialized
elements happens after any side-effected store to that element (and
hence zaps the sideeffect).  The rules for non-aggregates appear to be
as-if one builds a temporary object and then copy-constructs it into the
object -- clearly zapping any and all side-effects.  However for
aggregate initializations it looked like elements were initialized in
order -- so the side effect on a later element could overwrite the
initialization of an earlier element.

It wasn't entirely clear.

Looks like things are happening in the right order for this testcase. That is, the zeroing happens by virtue of it being in the global section, and the rest of the runtime initialization happening afterwards:

abulafia:/build/t/gcc$ cat a.cc
int array[10] = { array[3]=5, array[7]=3 };

int main()
{
  return 0;
}

assembly:
---------
        .size   array, 40
array:
        .zero   40

...
...

abulafia:/build/t/gcc$ gdb -n a.out -q
Reading symbols from a.out...(no debugging symbols found)...done.
(gdb) b main
Breakpoint 1 at 0x40055b
(gdb) r
Starting program: /home/build/t/gcc/a.out

Breakpoint 1, 0x000000000040055b in main ()
(gdb) x/4x &array
0x601080 <array>: 0x00000005 0x00000003 0x00000000 0x00000005
(gdb)

The above looks correct.

Now for the next example below I get what I intuitively expect, though I don't know if that's how it's defined in the standard:

int array[10] = { array[3]=5, 0x111, 0x222, 0x333 };

(gdb) x/4x &array
0x601040 <array>: 0x00000005 0x00000111 0x00000222 0x00000005

That is, the array[3]=5 overwrites the last 0x333.  I would expect that...

Is any of this incorrect?

Aldy


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]