C数组的范围初始化

时间:2011-10-18 07:32:06

标签: c arrays initialization

这个代码的哪里非常简单?

static void *gostruct[] = 
{
    [0 ... 255] = &&l_bad,
    ['\t'] = &&l_loop, [' '] = &&l_loop, ['\r'] = &&l_loop, ['\n'] = &&l_loop,
    ['"'] = &&l_qup,
    [':'] = &&l_loop,[','] = &&l_loop,
    ['['] = &&l_up, [']'] = &&l_down, // tracking [] and {} individually would allow fuller validation but is really messy
    ['{'] = &&l_up, ['}'] = &&l_down,
    ['-'] = &&l_bare, [48 ... 57] = &&l_bare, // 0-9
    ['t'] = &&l_bare, ['f'] = &&l_bare, ['n'] = &&l_bare // true, false, null
};

通过它可以清楚地看到它将一个包含256个条目的数组初始化为值&& l_bad,然后用特定值覆盖某些索引。但是这个代码不能在VS2010中编译,这是我有权访问的,所以我想知道这是有效的C代码。

注意:此代码段取自JSON parser on github,根据我的理解,它创建了用于处理JSON字符串的跳转表。

4 个答案:

答案 0 :(得分:9)

此构造称为 Designated Initializers 在指定的初始化程序中使用 Range 是GNU gcc特定的扩展。

  

要将一系列元素初始化为相同的值,请编写 [first ... last] = value   。这是一个GNU扩展。例如,

int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };

-pedantic编译它会告诉你。
请注意,它是不可移植的,因为它是特定于编译器的扩展。

答案 1 :(得分:3)

这是使用GNU C扩展名。

http://www.gnu.org/s/gnu-c-manual/gnu-c-manual.html

'as a GNU C extension, you can initialize a range of elements 
to the same value, by specifying the first and last indices, in the 
form [first] ... [last]'

'As a GNU C extension, you can also take the address of a label 
with the label address operator &&. The result is a void* pointer 
which can be used with goto.'

看起来这很可能被用作解析器的跳转表, 如果您打算将其移植到Windows,则需要重写整个部分。

您可能会发现您将实现一个简单的switch语句并替换 查找和goto跳转,像perl这样的东西可以帮助你'打字' excersise:)

答案 2 :(得分:2)

根据参考资料

  

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

范围和特定初始化程序都支持ISO C99,不仅是GNU扩展。您可以尝试在Visual Studio 2010中启用ISO C99(我不知道如何)。

参考:https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html

答案 3 :(得分:1)

在指定的初始值设定项中使用范围是gcc扩展名,标准C99不支持。

此外,代码采用标签的地址,我相信它也是gcc扩展名。

所以,这不是有效的C代码,只是有效的gcc c代码。