Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

explicit indexes in C array literals?

Tags:

The Linux kernel source has a lot of array literals like this:

enum {
  FOO,
  BAR
};

static const char* const names[] = {
  [FOO] = "foo", /* wtf is this? */
  [BAR] = "bar",
};

Here each line explicitly indicates the index within the array of the supplied value instead of relying on ordering.

I don't know the phrase to search for - what is this called? What standard defines it? (Or is it a GNU extension?) Can I do this in C++ or just plain C? Experimenting with gcc, I find with the above in test.c,

$ gcc --version
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE

these commands return success:

$ gcc -Wall -c test.c
$ gcc -Wall -c --std=c90 test.c
$ gcc -Wall -c --std=gnu90 test.c
$ gcc -Wall -c --std=iso9899:1990 test.c
$ gcc -Wall -c --std=c1x test.c

and these commands fail with various complaints about lambdas and operator=:

$ g++ -Wall -c test.c
$ g++ -Wall -c --std=c++98 test.c
$ g++ -Wall -c --std=gnu++98 test.c
$ g++ -Wall -c --std=c++0x test.c
$ g++ -Wall -c --std=gnu++0x test.c

That suggests this is valid C (in just about any dialect) but not C++. But I'm skeptical. I don't remember seeing this used anywhere but the Linux kernel. I also don't see it described in, for example, this list of constructs valid in C but not C++.

like image 310
Scott Lamb Avatar asked Jul 10 '13 21:07

Scott Lamb


People also ask

Is array a literal in C?

Compound literals were introduced in C99 standard of C. Compound literals feature allows us to create unnamed objects with given list of initialized values. In the above example, an array is created without any name. Address of first element of array is assigned to pointer p.

Can you index arrays in C?

Arrays in C are indexed starting at 0, as opposed to starting at 1. The first element of the array above is point[0]. The index to the last value in the array is the array size minus one. In the example above the subscripts run from 0 through 5.

What is an array index?

(definition) Definition: The location of an item in an array.

Is array a literal?

Array literalsAn array literal is a list of zero or more expressions, each of which represents an array element, enclosed in square brackets ( [] ). When you create an array using an array literal, it is initialized with the specified values as its elements, and its length is set to the number of arguments specified.


1 Answers

It's part of standard C (C99 and newer), called "designated initialization".

From 6.7.9 Initialization, paragraph 6:

If a designator has the form

[ constant-expression ]

then the current object ... shall have array type and the expression shall be an integer constant expression. If the array is of unknown size, any nonnegative value is valid.

And paragraph 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",
};

According to answers at this question, C++ doesn't support the same behaviour. Your compiler may provide extensions.

Perhaps more helpful to you (and a direct answer to your question) is the GCC documentation, which says:

In ISO C99 you can give the elements in any order, specifying the array indices or structure field names they apply to, and GNU C allows this as an extension in C90 mode as well. This extension is not implemented in GNU C++.

like image 164
Carl Norum Avatar answered Sep 30 '22 17:09

Carl Norum