1

I read piece of code like below:

#include <stdint.h>
typedef unsigned char u8;
int main(){
  enum { RA, R1, R2, R3, PC };
  u8 R[] = {
    [RA] = 0, 
    [R1] = 0,
    [R2] = 0,
    [R3] = 0,
    [PC] = 0,
  };
  return 0;
}

From objdump, I know every element in R[] is set to zero:

0000000000000000 <main>:
   0:   c7 44 24 fb 00 00 00    movl   $0x0,-0x5(%rsp)
   7:   00
   8:   c6 44 24 ff 00          movb   $0x0,-0x1(%rsp)
   d:   b8 00 00 00 00          mov    $0x0,%eax
  12:   c3                      retq

However, I haven't seen this in the book I'm learning from. Could you explain the detail?

4
  • I hope not. It is unreadable. Please boys and girls do not program this way Commented Mar 12, 2022 at 13:41
  • 1
    You can read about "array designators" here. However, they are not commonly used. Commented Mar 12, 2022 at 13:56
  • 1
    Why are you using typedef unsigned char u8; right after #include <stdint.h>? Just use the standard uint8_t. (For the pedants: Yes, uint8_t might not exist, but if it doesn't u8 isn't likely to be 8 bits either...) Commented Mar 12, 2022 at 13:58
  • The values of enum fields start at 0 and increment by 1 for each successive step (if not specified otherwise). In your case, RA is 0, R1 is 1 ... PC is 4 Commented Mar 12, 2022 at 14:12

1 Answer 1

3

The code you posted uses designated initializers. Although these are far more common when initializing elements of structures or unions, such designators can also be used for array elements.

In fact, this Draft C11 Standard gives an example that is very similar to the code you posted:

6.7.9 Initialization



33 EXAMPLE 9 Arrays can be initialized to correspond to the elements of an enumeration by using designators:

enum { member_one, member_two }; 
const char *nm[] = {
      [member_two] = "member two",
      [member_one] = "member one",
};

You can use such designators to initialize specific sub-objects of aggregate types (like structures and arrays). In the case of structures, those sub-objects will be the individual members; for arrays, they will be elements of the array.

A "non-designated" array initializer will set elements starting from index zero. Thus:

int arr[4] = {1,2,};

will initialize the array elements to 1 2 0 0. However, if you want to only explicitly initialize the second and third elements, then you can use a designator:

int arr[4] = { [1] = 1, 2 };

Note that, after any given designator, subsequent (non-designated) initial values will be applied to subsequent elements, in order, so the above line will set the initial values of arr to 0 1 2 0, respectively.

One can 'mix and mingle' designated and non-designated initialization:

int arr[4] = { [1] = 1, [3] = 2 };

This will set the elements to 0 1 0 2. In each of the above three examples, all elements not explicitly initialized will be implicitly initialized to the values they would have if they were declared as static (which will be zero for int data).

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

3 Comments

Thx for your great help !
Merely pointing to information elsewhere is not an adequate answer for Stack Overflow. An answer should explain what a designated initializer is and what it does. For example, it ought to state that [i] = 3 initializes the array element with index i to the value 3. Even the quoted text that was included in the answer does not state this.
Fair point, @Eric. I've added some further explanation and examples that (hopefully) makes this a better answer.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.