21

Linux 内核源代码有很多这样的数组字面量:

enum {
  FOO,
  BAR
};

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

在这里,每一行都明确地指示了所提供值的数组中的索引,而不是依赖于排序。

我不知道要搜索的短语 - 这叫什么?是什么标准定义的?(或者它是一个 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

这些命令返回成功:

$ 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

这些命令因对 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

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

4

2 回答 2

13

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

6.7.9 初始化,第 6 段:

如果指定人具有以下形式

[ constant-expression ]

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

第 33 段:

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

enum { member_one, member_two };
const char *nm[] = {
      [member_two] = "member two",
      [member_one] = "member one",
};

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

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

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

于 2013-07-10T21:21:01.710 回答
12

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

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

int bla[16] = {[5] = 42, [9] = 42};

bla[5]这将 element和bla[9]to42以及所有剩余的元素初始化为0。指定是 之间的整数常量表达式[]

enum {
  FOO,
  BAR
};

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

这里的名称是一个枚举常量。这是允许的,因为枚举常量在 C 中被视为整数常量表达式。

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

于 2013-07-10T21:21:29.533 回答