94
static uint8_t togglecode[256] = {
    [0x3A] CAPSLOCK,
    [0x45] NUMLOCK,
    [0x46] SCROLLLOCK
};

What's the meaning of [0x3A] here? I have only learned statements like int a[2] = {1, 2};

Burhan Ali
  • 2,258
  • 1
  • 28
  • 38
akirast
  • 1,137
  • 1
  • 8
  • 10
  • 1
    Most likely it's a compiler extension that lets you initialize specific array entries (at given indices) w/o filling in the rest. – Alexey Frunze Mar 24 '12 at 06:49

4 Answers4

87

It means initialise the n-th element of the array. The example you've given will mean that:

togglecode[0x3A] == CAPSLOCK
togglecode[0x45] == NUMLOCK
togglecode[0x46] == SCROLLLOCK

These are called "designated initializers", and are actually part of the C99 standard. However, the syntax without the = is not. From that page:

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

huon
  • 94,605
  • 21
  • 231
  • 225
44

According to the GCC docs this is ISO C99 compliant. They refer to it as "Designated Initializers":

To specify an array index, write `[index] =' before the element value. For example,

 int a[6] = { [4] = 29, [2] = 15 };

is equivalent to

 int a[6] = { 0, 0, 15, 0, 29, 0 };

I've never seen this syntax before, but I just compiled it with gcc 4.4.5, with -Wall. It compiled successfully and gave no warnings.

As you can see from that example, it allows you to initialize specific array elements, with the others being set to their default value (0).

Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
  • 2
    There is no partial initialization of objects. See [C99 6.7.8p19](https://port70.net/~nsz/c/c99/n1256.html#6.7.8p19) **[...] all subobjects that are not initialized explicitly shall be initialized implicitly [...]** to zero. – pmg Jan 26 '22 at 17:16
  • FYI: this works fine in C, but C++17 doesn't like it: `sorry, unimplemented: non-trivial designated initializers not supported`. I'm trying to see if I can make C++ accept it or something like it. – Gabriel Staples Jan 27 '22 at 01:07
  • From the older documentation in the answer, as well as from the [latest gcc manual reference page for GCC 11.2.0](https://gcc.gnu.org/onlinedocs/gcc-11.2.0/gcc/Designated-Inits.html#Designated-Inits), it appears g++ does *not* allow this syntax as an extension in C++. That's too bad. It 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++.` – Gabriel Staples Jan 27 '22 at 03:46
  • The last example code in the "Designated initializers" section of this page (https://en.cppreference.com/w/cpp/language/aggregate_initialization) also indicates this syntax is valid in C but not in C++. – Gabriel Staples Jan 27 '22 at 03:47
  • My follow-up question: [Initializing std::vector with square brackets \[\] inside; what is happening?](https://stackoverflow.com/q/70873232/4561887) – Gabriel Staples Jan 27 '22 at 04:09
16

That was introduced in C99 and it's called a designated initialiser.

It basically allows you to set specific values in an array with the rest left as defaults.

In this particular case, the array indexes are the keyboard scan codes. 0x3a is the scan code in set #1 (see section 10.6) for the CapsLock key, 0x45 is NumLock and 0x46 is ScrollLock.

On the first link above, it states that:

int a[6] = { [4] = 29, [2] = 15 };

is equivalent to:

int a[6] = { 0, 0, 15, 0, 29, 0 };

Interestingly enough, though the link states that = is necessary, that doesn't appear to be the case here. That's not part of the standard but is a hangover from a rather old version of gcc.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • To respond to your closing line that `=` isn't totally necessary: from your [designated initializer](http://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html#Designated-Inits) link: `An alternative syntax for this which has been obsolete since GCC 2.5 but GCC still accepts is to write '[index]' before the element value, with no '='.` – Gabriel Staples Jan 26 '22 at 17:13
13

It's (close to) the syntax of designated initializers, a C99 feature.

Basically, it initializes parts of an array, for example;

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

Intializes the second value of the array to 6, and the third to 3.

In your case the array offsets happen to be in hex (0x3a) which initializes the 58'th element of the array to the value of CAPSLOCK which presumably is defined in the code above the code you're showing.

The version in your code without the = seems to be a gcc specific extension.

Joachim Isaksson
  • 176,943
  • 25
  • 281
  • 294
  • There is no partial initialization of objects. See [C99 6.7.8p19](https://port70.net/~nsz/c/c99/n1256.html#6.7.8p19) **[...] all subobjects that are not initialized explicitly shall be initialized implicitly [...]** to zero. Basically it initializes the designated members to the given values, the other members to zero. – pmg Jan 26 '22 at 17:17