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内核以外的任何地方使用过。我也没有在例如this list of constructs valid in C but not C++中描述它。
答案 0 :(得分: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", };
根据answers at this question,C ++不支持相同的行为。您的编译器可能会提供扩展。
或许对您有帮助(并直接回答您的问题)是GCC documentation,其中说:
在ISO C99中,您可以按任何顺序给出元素,指定它们适用的数组索引或结构字段名称,GNU C也允许它作为C90模式的扩展。此扩展未在GNU C ++中实现。
答案 1 :(得分:11)
这是一个c99 指定初始化程序。
指定初始值设定项允许您以任何顺序初始化数组或结构。省略了省略的元素,就好像它们是静态对象一样。
int bla[16] = {[5] = 42, [9] = 42};
将元素bla[5]
和bla[9]
初始化为42
,将所有剩余元素初始化为0
。
该名称是[]
之间的整数常量表达式。
enum {
FOO,
BAR
};
static const char* const names[] = {
[FOO] = "foo", /* wtf is this? */
[BAR] = "bar",
};
这里的名称是枚举常量。这是允许的,因为枚举常量被认为是C中的整数常量表达式。
此功能是C功能,在C ++中不存在。