C数组文字中的显式索引?

Sco*_*amb 20 c c++

Linux内核源码有很多这样的数组文字:

enum {
  FOO,
  BAR
};

static const char* const names[] = {
  [FOO] = "foo", /* wtf is this? */
  [BAR] = "bar",
};
Run Code Online (Sandbox Code Playgroud)

这里每一行显式指示所提供值的数组中的索引,而不是依赖于排序.

我不知道要搜索的短语 - 这叫什么?什么标准定义它?(或者它是GNU扩展吗?)我可以用C++或纯C做到这一点吗?试验gcc,我发现上面的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
Run Code Online (Sandbox Code Playgroud)

这些命令返回成功:

$ 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
Run Code Online (Sandbox Code Playgroud)

这些命令失败了,各种关于lambdas的抱怨和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
Run Code Online (Sandbox Code Playgroud)

这表明这是有效的C(几乎任何方言),但不是C++.但我持怀疑态度.我不记得看到这个在Linux内核以外的任何地方使用过.我也没有看到它描述,例如,这个结构列表在C中有效而不是C++.

Car*_*rum 13

它是标准C(C99和更新版本)的一部分,称为"指定初始化".

6.7.9初始化,第6段:

如果指定者有表格

[ constant-expression ]
Run Code Online (Sandbox Code Playgroud)

然后当前对象...应具有数组类型,表达式应为整数常量表达式.如果数组的大小未知,则任何非负值都是有效的.

第33段:

示例9可以使用指示符初始化数组以对应枚举的元素:

enum { member_one, member_two };
const char *nm[] = {
      [member_two] = "member two",
      [member_one] = "member one",
};
Run Code Online (Sandbox Code Playgroud)

根据这个问题的答案,C++不支持相同的行为.您的编译器可能提供扩展.

或许对您更有帮助(并直接回答您的问题)是GCC文档,其中说:

在ISO C99中,您可以按任何顺序给出元素,指定它们适用的数组索引或结构字段名称,GNU C也允许它作为C90模式的扩展.此扩展未在GNU C++中实现.


oua*_*uah 11

这是一个c99 指定初始化程序.

指定初始值设定项允许您以任何顺序初始化数组或结构.省略了省略的元素,就好像它们是静态对象一样.

int bla[16] = {[5] = 42, [9] = 42};
Run Code Online (Sandbox Code Playgroud)

此初始化元件bla[5]bla[9]42和所有剩余的元素0.该名称是一个整数常量表达式[].

enum {
  FOO,
  BAR
};

static const char* const names[] = {
  [FOO] = "foo", /* wtf is this? */
  [BAR] = "bar",
};
Run Code Online (Sandbox Code Playgroud)

这里的名称是枚举常量.这是允许的,因为枚举常量被认为是C中的整数常量表达式.

此功能是C功能,在C++中不存在.

  • 我相信他们通常被称为散文中的*指定*初始化者,而不是*指定*初始化者.C99规范并未将它们称为它们,但GCC文档将它们称为指定的初始化程序.它是指定的初始化程序,而不是初始化的名称. (3认同)
  • @ 0x499602D2,您可能会考虑此行为标准化之前的时间,或者可能是关于范围样式的初始化程序,它们是GNU扩展.像[[1 ... 6] = 12`这样的东西.链接:http://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html#Designated-Inits (2认同)