6

Consider the following simple program:

#include <stdio.h>

int main(void)
{
    int a[5] = { a[2] = 1 };
    printf("%d %d %d %d %d\n", a[0], a[1],a[2], a[3], a[4]);
}

With GCC 7.3.0 this outputs

1 0 1 0 0

Considering that a[1] is zero, it seems that the initialization is similar to

int a[5] = { 1 };
a[2] = 1;

The question is: While initializers could be any generic expression, in which order is the initialization and assignments made?

Is this even valid and well-defined? Could it be implementation-defined, undefined or maybe unspecified?


This question is related to the question Confusion about Array initialization in C.

11
  • 2
    Yeah it seems that this is VERY similar to the other question but just handles another aspect. I am not entirely sure if duplicate but a good answer to the other question could cover this topic. Interestingly this is voted much higher than the other question, which could be another indicator that upvotes are more likly given to high rep users. This is in no way a critic @OP, but I found this interesting. Commented Sep 13, 2018 at 7:06
  • 3
    Let's ask the real question! Why does int a[5] = { a[2] = 1, a[3] =2 }; gives us 1 2 0 0 0?! Commented Sep 13, 2018 at 7:09
  • 3
    I don't see how this is different to the other question. You basically answered the other question saying "I don't really know what's going on here" and posted another copy of the same question. Any actual useful answer to this question would answer the other one too, and vice versa Commented Sep 13, 2018 at 7:16
  • 1
    @hellow Now it gets nasty... I get 1 2 1 2 0 for your code with GCC 5.4.0. Commented Sep 13, 2018 at 7:22
  • 1
    I've posted a language-lawyery answer to the other question. Commented Sep 13, 2018 at 8:08

1 Answer 1

0

While I cannot state, that I am an ISO-expert, here is what I found out with the help of godbolt.

First I built the sample with the help of -fsanitize=undefined, which gives a good indication of undefined behavoir. Neither GCC nor clang were complaining.

Next I looked at the various stages gcc performs, in this case the gimple stage

foo ()
{
  int a[5];

  try
    {
      # DEBUG BEGIN_STMT
      a = {};
      a[2] = 1;
      _1 = a[2];
      a[0] = _1;
      # DEBUG BEGIN_STMT
      _2 = a[4];
      _3 = a[3];
      _4 = a[2];
      _5 = a[1];
      _6 = a[0];
      printf ("%d %d %d %d %d\n", _6, _5, _4, _3, _2);
    }
  finally
    {
      a = {CLOBBER};
    }
}

Here you can see, that first the array a is defined, then 1 is assigned to a[2], afterwards that result (1, because it is an assignment) is assigned to the first element of a. The other in indices are left to 0 and therefore the pattern 1 0 1 0 0 is printed out.

Sign up to request clarification or add additional context in comments.

1 Comment

The question is what the standard says, not what a compiler does

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.