7

I came across the following code which declares char * array in C in a non-standard way:

    /* Message Type description array */ 
    char *msgType[M_LAST_MSG] = 
    {    
       [M_INIT_MSG]     "Init", 
       [M_RESET_MSG]    "Serdes Reset"
    };

M_INIT_MSG, M_RESET_MSG and M_LAST_MSG are enumerations with corresponding values of 0, 1 and 2. According to the formal C documentations, the variables inside this array are string (literals) so what is the purpose of using those enumerations in that manner and is there any documentation to back it up?

Compiled with ARM gcc compiler gcc-arm-none-eabi.

4
  • 3
    You are probably missing = in your initializations: [M_INIT_MSG] = "Init" etc. Search for designated initializers. Commented Aug 2, 2016 at 13:17
  • 1
    No, I didn't miss it. Answer edited. Commented Aug 2, 2016 at 13:22
  • 1
    Talking about standard/non-standard and then linking to a gcc extension is probably not a good idea... But what in the linked page is not clear? It is an obsolete gcc extension, did you even read the page? From the page: "An alternative syntax for this that has been obsolete since GCC 2.5 but GCC still accepts is to write ‘[index]’ before the element value, with no ‘=’." Commented Aug 2, 2016 at 13:48
  • Yes I read it, thank you. This explain my question. Commented Aug 2, 2016 at 13:58

2 Answers 2

6

This syntax allows you to initialize specific elements of an array by index. You can use either int or enum values to specify which array element to initialize. This way, the values you assign don't need to be consecutive.

If for example you had this:

int x[5] = { [2] 3, [4] 7 };

It would be equivalent to this:

int x[5] = { 0, 0, 3, 0, 7 };

In the above example, the enum values specify that elements 0 and 1 of the array are initialized to "Init" and "Serdes Reset".

From section 6.7.8 of the C99 standard:

18 Each designator list begins its description with the current object associated with the closest surrounding brace pair. Each item in the designator list (in order) specifies a particular member of its current object and changes the current object for the next designator (if any) to be that member. The current object that results at the end of the designator list is the subobject to be initialized by the following initializer.

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

EDIT:

Note that the syntax from the standard includes a = while OP's example does not. The syntax without = is apparently an old syntax supported by GCC. Compiling OP's example gives the following warning:

warning: obsolete use of designated initializer without ‘=’

The GCC documentation states the following:

An alternative syntax for this that has been obsolete since GCC 2.5 but GCC still accepts is to write ‘[index]’ before the element value, with no ‘=’.

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

2 Comments

The syntax without an equal sign is GNU specific.
That does not answer why the syntax in the question works. OP apparently is aware about the standard syntax.
3

That's a GNU extension. It was standardized in C99 with slightly different syntax, namely an equal sign between the [index] and the value and no way to specify a range of indices. They are called designated initializers.

The C standard shows an example of probably the most widespread use, provide a string description for enums:

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

It even allows nifty stuff like

EXAMPLE 11 Designators can be used to provide explicit initialization when unadorned initializer lists might be misunderstood:

struct { int a[3], b; } w[] =
    { [0].a = {1}, [1].a[0] = 2 };

3 Comments

Mind linking to the documentation?
@CinCout, C11 draft 6.7.9 Initialization
I missed the lack of an equal sign. I revised the 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.