tags:

views:

271

answers:

3

I found this in initramfs.c, I haven't seen this syntax before, could some one explain what it is doing?

static __initdata int (*actions[])(void) = {
  [Start]   = do_start,
  [Collect] = do_collect,
  [GotHeader] = do_header,
  [SkipIt]  = do_skip,
  [GotName] = do_name,
  [CopyFile]  = do_copy,
  [GotSymlink]  = do_symlink,
  [Reset]   = do_reset,
};

Source Code (line 366): initramfs.c

+2  A: 

Designators in an Array Initialization

The bracketed expressions are called designators, and that's syntax to initialize an array or structure by naming the fields or elements rather than just by ordering the initializers in the same sequence as the declaration.

DigitalRoss
interesting feature
Lucas
+12  A: 

This is an out-of-sequence array initialization by index. It's like writing

actions[Start] = do_start;
actions[Collect] = do_collect;

except that you can do it as a static initializer.

Variable Length Coder
You'll find `Start`, `Collect`, etc. end up defined as constants somewhere.
Carl Norum
Well that is simple enough. Thanks!
Seamus
What is this used for? I mean, an out-of-sequence array initialization, not the actual code. Isn't it simpler to do the code as you did?
Carla Álvarez
@Carla Álvarez - The syntax Seamus is asking about initializes at declaration time, which for a global/static variable means it happens at compile time. The other syntax, mentioned by Variable Length Coder, initializes at runtime, which is unnecessary if you can just bake it into the binary in the ELF data section.
asveikau
+10  A: 

This is a feature from ISO C99 known as designated initializers. It creates an array and initializes specific elements of that array, not necessarily the first N in order. It's equivalent to the following snippet:

static __initdata int (*actions[SOME_SIZE])(void);
actions[Start]   = do_start;
actions[Collect] = do_collect;
actions[GotHeader] = do_header;
actions[SkipIt]  = do_skip;
actions[GotName] = do_name;
actions[CopyFile]  = do_copy;
actions[GotSymlink]  = do_symlink;
actions[Reset]   = do_reset;

Except that the array will only be as large as it needs to (equal in size to one more than the largest index), and it can be initialized statically at global scope -- you can't run the above code at global scope.

This is not a feature of ANSI C89, but GCC provides this feature as an extension even when compiling code as C89.

Adam Rosenfield