这个代码的哪里非常简单?
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字符串的跳转表。
答案 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(我不知道如何)。
答案 3 :(得分:1)
在指定的初始值设定项中使用范围是gcc扩展名,标准C99不支持。
此外,代码采用标签的地址,我相信它也是gcc扩展名。
所以,这不是有效的C代码,只是有效的gcc c代码。