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.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Neither clang nor gcc complain with undefined sanitizer, so I would say it is legal? :D https://wandbox.org/permlink/AFMWQ0qv1rojbeRf – hellow Sep 13 '18 at 06:35
  • @melpomene not exactly, because the question here is "The question is: While initializers could be any generic expression, in which order is the initialization and assignments made?" – hellow Sep 13 '18 at 06:41
  • The question there is "*I don't understand, why does `a[0]` print 1 instead of 0? Is it undefined behaviour?*", which amounts to the same thing. Someprogrammerdude's answer there is simply incomplete. – melpomene Sep 13 '18 at 06:42
  • 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. – Kami Kaze Sep 13 '18 at 07: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`?! – hellow Sep 13 '18 at 07: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 – M.M Sep 13 '18 at 07:16
  • 1
    @hellow Now it gets nasty... I get `1 2 1 2 0` for your code with GCC 5.4.0. – Gerhardh Sep 13 '18 at 07:22
  • @Gerhardh I see, gcc vs clang here. Ouh, damn! :D – hellow Sep 13 '18 at 07:23
  • The answer is in another castle err question: https://stackoverflow.com/a/52308631/4961259 – Kami Kaze Sep 13 '18 at 07:34
  • 1
    I've posted a language-lawyery answer to the other question. – melpomene Sep 13 '18 at 08:08
  • 1
    I think the answer to your question is that the standard doesn't preclude that type of initialization where you have a `designator[const]` as part of the *initializer-list*, so it is not something specifically excluded, but other than the `designator[const]` description isn't something that much text was devoted to either, see [C11 Standard - 6.7.9 Initialization(p6) (draft - n1570)](http://port70.net/~nsz/c/c11/n1570.html#6.7.9p6). You would think another sentence or two wouldn't have killed them. Also, if there is more in some later proposed draft to C17 or 20, I have not seen it. – David C. Rankin Sep 13 '18 at 08:18

1 Answers1

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.

hellow
  • 12,430
  • 7
  • 56
  • 79